home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / packet / thenet / x1j4_src / tnl1.mac < prev    next >
Encoding:
Text File  |  1995-02-03  |  106.1 KB  |  2,341 lines

  1. ; ***********************************************************************
  2. ; *                                                                     *
  3. ; *                                                                     *
  4. ; *    *****                      *****                                 *
  5. ; *      *****                  *****                                   *
  6. ; *        *****              *****                                     *
  7. ; *          *****          *****                                       *
  8. ; *  ***************      ***************                               *
  9. ; *  *****************  *****************                               *
  10. ; *  ***************      ***************                               *
  11. ; *          *****          *****          The Net.                     *
  12. ; *        *****              *****        Portable. Compatible.        *
  13. ; *      *****                  *****      Public Domain.               *
  14. ; *    *****                      *****    By NORD><LINK.               *
  15. ; *                                                                     *
  16. ; *                                                                     *
  17. ; *                                                                     *
  18. ; *    TNL1.MAC   -   Z80 Level 1, Hardwareanpassungen, Interrupts      *
  19. ; *                                                                     *
  20. ; *    angelegt:      DC4OX                                             *
  21. ; *    modifiziert:                                                     *
  22. ; *                                                                     *
  23. ; ***********************************************************************
  24.  
  25. ; modifications by G8KBB
  26. ;
  27. ; 1 put .z80 mode on
  28. ; 2 change definitions of variables to 'global' so they go into
  29. ;   uninitialised space not into rom data segment
  30. ; 3 define .begin to fool the compiler
  31. ; 4 change definition of minmem() so that it reads from Fremem
  32. ;   an address written by the linker rather than using the address
  33. ;   of fremem, where it is the last variable in udata.
  34. ; 5 clean up definitions for case sensitivity in many cases
  35. ; 6 alter STAled & CONled to use decEI & DIinc functions
  36. ; 7 Add additional default definitions for extended operation
  37. ; 8 Add KISS code to crosslink driver
  38. ; 9 Add code for host mode operation
  39. ;   Change stack initialisation in L1INIT
  40. ;   Incorporate DF2AU HDLC IRQ lockup bug
  41. ;   Add stats gathering for L1 bits
  42. ;   Comment out the STAled & CONled routines
  43. ;   Factor out raise_dcd_ as a function from CTXINI
  44. ;   Add devmeter support to SIASRC
  45. ;   use ex & exx instead of lods of push / pops
  46. ;   add a small reset delay to L1INIT
  47.  
  48. ; released as thenet x-1j september 1993
  49.  
  50.     .z80
  51.  
  52. ;
  53. ; Achtung :  Hier wird mit "Crosslink" ausschliesslich die Verbindung
  54. ;            zweier TNC's ueber die RS232-Schnittstelle bezeichnet.
  55. ;            Somit wird der RS232-Kanal zwischen 2 TNC's als
  56. ;            "Crosslink-Kanal" bezeichnet, der Modem-Kanal als
  57. ;            "HDLC-Kanal".
  58. ;
  59.  
  60.  
  61.  
  62.  
  63.  
  64. ; =======================================================================
  65. ;                                                                        
  66. ;   Equates                                                   
  67. ;                                                                        
  68. ; =======================================================================
  69.  
  70.  
  71.  
  72. ;
  73. ; benutzte "Magic Number" zum RAM-Test Warmstart/Kaltstart
  74. ;
  75. MAGIC     equ   4D5Ah
  76.  
  77.  
  78.  
  79. ;
  80. ; Hardware-I/O-Ports
  81.  
  82. SIADAT    equ   0               ; SIO Kanal A (HDLC)  Data
  83. SIACTL    equ   1               ; SIO Kanal A (HDLC)  Control
  84. SIBDAT    equ   2               ; SIO Kanal B (RS232) Data
  85. SIBCTL    equ   3               ; SIO Kanal B (RS232) Control
  86.  
  87. ADC       equ   32        ; adc i/o port
  88. ADC_CH1   equ   4        ; command to convert port 1 data
  89. ADC_CH2   equ   5        ; command to convert port 2 data
  90.  
  91. ;
  92. ; niedrigste RAM-Speicherstelle
  93. ;
  94. RAMBOT    equ   8000h
  95.  
  96.  
  97.  
  98. ;
  99. ; ASCII-Kontrollzeichen
  100. ;
  101. ASTX      equ   02h             ; ASCII Start of Text      = Control B
  102. AETX      equ   03h             ; ASCII End of Text        = Control C
  103. ADLE      equ   10h             ; ASCII Data Link Escape   = Control P
  104. ACAN      equ   18h             ; ASCII Cancel             = Control X
  105. AESC      equ   1Bh             ; ASCII Escape
  106.  
  107. FEND      equ   0c0h            ; KISS frame start / end
  108. FESC      equ   0dbh            ; KISS frame escape
  109. TFEND     equ   0dch            ; KISS frame start / end shift char
  110. TFESC     equ   0ddh            ; KISS frame escape shift char
  111.  
  112.  
  113.  
  114. ;
  115. ; Hostterminal FIFO-Groessen
  116. ;
  117. HORXFL    equ   256             ; RX FIFO Laenge
  118. HOTXFL    equ   256             ; TX FIFO Laenge
  119.  
  120.  
  121.  
  122.  
  123.  
  124. ; =======================================================================
  125. ;                                                                        
  126. ;   Arbeitsspeicher                                                      
  127. ;                                                                        
  128. ; =======================================================================
  129.  
  130. ;          dseg
  131.  
  132.     global    RAMVEC,16
  133. ;RAMVEC:   ds    16      ; Interrupt Vektor im RAM
  134.  
  135. ;
  136. ; Hostkanal, SIO Kanal B, RS232-Schnittstelle,
  137. ; wenn Hostterminal angeschlossen
  138. ;
  139. ;HORXCC:   ds    2       ; RX "character count"   Anzahl Zeichen 
  140. ;HORXFI:   ds    HORXFL  ; RX "fifo"              FIFO-Ringspeicher
  141. ;HORXIP:   ds    2       ; RX "input pointer"     Eingangszeiger
  142. ;HORXOP:   ds    2       ; RX "output pointer"    Ausgangszeiger
  143. ;HOTXCC:   ds    2       ; TX "character count"   Anzahl Zeichen
  144. ;HOTXFI:   ds    HOTXFL  ; TX "fifo"              FIFO-Ringspeicher
  145. ;HOTXIP:   ds    2       ; TX "input pointer"     Eingangszeiger
  146. ;HOTXOP:   ds    2       ; TX "output pointer"    Ausgangszeiger
  147.     global    HORXCC,2      
  148.     global    HORXFI,HORXFL 
  149.     global    HORXIP,2      
  150.     global    HORXOP,2      
  151.     global    HOTXCC,2      
  152.     global    HOTXFI,HOTXFL 
  153.     global    HOTXIP,2
  154.     global    HOTXOP,2      
  155.  
  156. ;
  157. ; SIO Kanal B, RS232-Schnittstelle
  158. ;
  159. ;SIBWR5:   ds    1       ; Sicherung WR5, Tx-Modus
  160. ;SIBRR0:   ds    1       ; Sicherung RR0, Status
  161.     global    SIBWR5,1
  162.     global    SIBRR0_,1
  163.  
  164. ;
  165. ; Crosslink, SIO Kanal B, RS232-Schnittstelle,
  166. ; wenn TNC im Crosslink betrieben
  167. ;
  168. ;CRXSTA:   ds    1       ; RX "state"
  169.                         ;    0 - RX inaktiv
  170.                         ;    1 - RX aktiv, innerhalb Frame
  171.                         ;    2 - RX aktiv, letztes Zeichen war DLE, naechstes
  172.                         ;        wird nicht interpretiert (STX/ETX/DLE)
  173.                         ;    3 - Frameende, naechstes Zeichen ist Checksum
  174.                         ;    4 - KISS ignore command byte
  175. ;CRXFCS:   ds    1       ; RX "frame checksum" (8 Bit, Summe modulo 256)
  176. ;CTXSTA:   ds    1       ; TX "state"
  177.                         ;    0 - TX inaktiv
  178.                         ;    1 - nachdem Port frei wird (DTR high)
  179.                         ;        (ASync-)WAIT-Sendesequenz eineiten
  180.                         ;    2 - nachdem Port frei wird (DTR high)
  181.                         ;        Nicht-(Async-)WAIT-Sendesequenz einleiten
  182.                         ;    3 - (Async-)WAIT abwarten
  183.                         ;    4 - Vorlauftraeger (CTS low) gesetzt, 
  184.                         ;        2,5 msec warten
  185.                         ;    5 - TX aktiv, innerhalb Frame
  186.                         ;        (vor ETX/Checksumme)
  187.                         ;    6 - TX aktiv, Frameende, ETX gesendet,
  188.                         ;        weitere Frames vorhanden
  189.                         ;    7 - TX aktiv, Frameende, ETX gesendet,
  190.                         ;        keine weiteren Frames vorhanden
  191.                         ;    8 - TX aktiv, Frameende, Checksumme gesendet,
  192.                         ;        weitere Frames vorhanden
  193.                         ;    9 - TX aktiv, Frameende, Checksumme gesendet,
  194.                         ;        keine weiteren Frames vorhanden
  195.                         ;   10 - wie 9, vorletztes Zeichen aus internem
  196.                         ;        SIO-FIFO gesendet
  197.                         ;   11 - wie 9, letztes Zeichen aus internem 
  198.                         ;        SIO-FIFO gesendet
  199.                         ;   12 - KISS frame start
  200. ;CTXFCS:   ds    1       ; TX "frame checksum" (8 Bit, Summe modulo 256)
  201. ;CTXCSA:   ds    1       ; TX "character save" fuer Zeichen mit DLE-Vorlauf
  202.     global    CRXSTA,1
  203.     global    CRXFCS,1
  204.     global    CTXSTA,1
  205.     global    CTXFCS,1
  206.     global    CTXCSA,1
  207.  
  208. ;
  209. ; HDLC-Kanal, SIO Kanal A, PR-Modemschnittstelle
  210. ;
  211. ;SIAWR5:   ds    1       ; Sicherung WR5, Tx-Modus
  212. ;SIARR0:   ds    1       ; Sicherung RR0, Status
  213. ;HRXSTA:   ds    1       ; RX "state"
  214.                         ;    0 - RX ausserhalb Frame
  215.                         ;    1 - RX innerhalb Frame
  216. ;HRXLCH:   ds    1       ; RX "last character" 1-Zeichen-FIFO, Zeichen erst
  217.                         ;   gueltig, wenn Nicht-Frameende-Status von SIO
  218. ;HTXSTA:   ds    1       ; TX "state"
  219.                         ;    0 - TX inaktiv
  220.                         ;    1 - nachdem Port frei wird (DCD low)
  221.                         ;        WAIT-Sendesequenz einleiten
  222.                         ;    2 - nachdem Port frei wird (DCD low)
  223.                         ;        Nicht-WAIT-Sendesequenz einleiten
  224.                         ;    3 - WAIT warten
  225.                         ;    4 - TX aktiv, PTT, TXDELAY abwarten
  226.                         ;    5 - TX aktiv, innerhalb Frame Datenbytes
  227.                         ;    6 - TX aktiv, letztes Datenbyte fuer Frame
  228.                         ;        gesendet, weitere Frames vorhanden
  229.                         ;    7 - TX aktiv, letztes Datenbyte fuer Frame
  230.                         ;        gesendet, keine weiteren Frames vorhanden
  231.                         ;        (mit 6 oder 7 laeuft TX in den TX-Underrun/
  232.                         ;        EoM-Interrupt, naechster TX-Buffer-Empty-
  233.                         ;        Interrupt :  1. CRC-Byte hat SIO verlassen) 
  234.                         ;    8 - TX aktiv, CRC verlaesst SIO
  235.                         ;    9 - TX aktiv, Frameendeflag verlaesst SIO
  236.                         ;   10 - TX aktiv, Frameendeflag hat SIO komplett
  237.                         ;        verlassen
  238.     global    SIAWR5,1
  239.     global    SIARR0,1
  240.     global    HRXSTA,1
  241.     global    HRXLCH,1
  242.     global    HTXSTA,1
  243.  
  244. ;
  245. ; Zaehler
  246. ;
  247. ;TICDIV:   ds    1       ; Zaehler bis 12, 1200Hz Interrupts -> 10msec
  248. ;HTXWAI:   ds    1       ; 10msec HDLC-TX-Wartezaehler (WAIT/TXDELAY) 
  249. ;CTXWAI:   ds    1       ; 1200Hz Crosslink-TX-Wartezaehler (Async-WAIT)
  250.     global    TICDIV,1
  251.     global    HTXWAI,1
  252.     global    CTXWAI,1
  253.  
  254. ;
  255. ; Sonstiges
  256. ;
  257. ;DEICNT:   ds    1       ; Interrupt Verbietungsstufe
  258. ;RAMTOP:   ds    2       ; oberste verfuegbare RAM-Speicherstelle
  259. ;URAND:    ds    2       ; (fuer random(), damit Gleichverteilung)
  260.     global    DEICNT,1
  261.     global    RAMTOP,2
  262.     global    URAND,2
  263.  
  264. ;sig_level: ds   1       ; temp store for smeter reading
  265.      global  sig_level_,1
  266.  
  267. ; =======================================================================
  268. ;                                                                        
  269. ;   Code                                                                 
  270. ;                                                                        
  271. ; =======================================================================
  272.  
  273.           cseg
  274.  
  275.  
  276.  
  277. ; +---------------------------------------------------------------------+
  278. ; |                                                                     |
  279. ; | Reset-Einsprungsvektor, RST-Vektoren.                               |
  280. ; |                                                                     |
  281. ; +---------------------------------------------------------------------+
  282.  
  283.  
  284.           public reset_, .begin
  285.  
  286.           public .eq, .ne, .ug, .an, .sb
  287.  
  288. .begin    equ    $
  289. reset_:   jp    L1INIT                  ; Resetvektor
  290.  
  291.       db     0,0,0,0,0
  292. ;
  293. ; Runtime speedup & code size. These are all runtine functions
  294. ; removed from the file SUPPORT.MAC. They have been replaced by
  295. ; RST as RST is shorter and quicker than CALL. These are the
  296. ; most frequently used functions. The remainder of SUPPORT.MAC
  297. ; has been appended to CRUN.MAC
  298. ;
  299. ; RST 8        .an    ; return HL = HL & DE
  300. ;
  301. .an:    ld      A,H
  302.     and    D
  303.     ld     H,A
  304.     ld     A,L
  305.     and    E
  306.     ld     L,A
  307.     or    h
  308.     ret
  309. ;
  310. ; RST 10    .ne
  311. ;
  312. .ne:    xor   a
  313.     sbc   hl,de
  314.     jr    z,.false
  315. .true:    ld    hl,1    
  316.     ld    a,l
  317.     or    h
  318.     ret
  319.  
  320.     db    0,0,0,0,0
  321. ;
  322. ; RST 18 unusable as RST 10 is too long
  323. ;
  324. ; RST 20    .ug
  325. ;
  326. .ug:    xor   a
  327.     sbc   hl,de
  328.     jr    c,.true
  329.     jr    .false
  330.  
  331.     db    0
  332.  
  333. ;
  334. ; RST 28    .sb
  335. ;
  336. .sb:    ex    de,hl
  337.     or    a
  338.     sbc   hl,de
  339.     ret
  340.  
  341.     db    0,0,0
  342.  
  343. ;
  344. ; RST 30    .eq
  345. ;
  346. .eq:    xor   a
  347.     sbc   hl,de
  348.     jr    z,.true
  349. .false: xor   a        ; Clear carry (and A)
  350.     ld    h,a    ; Set HL = 0;
  351.     ld    l,a
  352.     ret
  353.  
  354.     db    0,0
  355.  
  356. ;
  357. ; RST 38 unusable
  358. ;
  359.  
  360.  
  361. ; +---------------------------------------------------------------------+
  362. ; |                                                                     |
  363. ; | Default-Parameter.                                                  |
  364. ; |                                                                     |
  365. ; +---------------------------------------------------------------------+
  366.  
  367.           public   DEFCAL_, DEFIDE_, DEFDES_, DEFWQU_, DEFCH0_, DEFCH1_
  368.           public   DEFOBC_, DEFOBB_, DEFBRI_, DEFTLI_, DEFTTO_, DEFTTR_
  369.           public   DEFTAC_, DEFTBS_, DEFTWI_, DEFCON_, DEFNOA_, DEFPER_
  370.           public   DEFSLO_, DEFRAK_, DEFMAF_, DEFL2T_, DEFLT2_, DEFLT3_
  371.           public   DEFRPA_, DEFVAL_, DEFBEA_, DEFCQ_,  DEFDPA_, DEFXFP_
  372.           public   DEFESC_, DEFTP_,  DEFPWD_, DEFINF_
  373.           public   DEFCW_,  DEFHOS_, DEFKIS_, DEFCWS_, DEFMHL_
  374.           public   beadil_, DEFBCN_, DEFBR1_, DEFALG_, DEFCSB_, DEFBIN_
  375.           public   DEFNOHASH_, DEFMYIPADDR_, DEFIPBCAST_, DEFIPL2MODES_
  376.           public   DEFIPTTL_, DEFIPENABLE_, DEFHLP_
  377.           public   DEF_MTU_I_MAX_, DEF_MTU_L2_MAX_
  378.           public   DEF_MTU_IP0_, DEF_MTU_IP1_, DEF_MTU_IPN_
  379.           public   DEFRECONNECT_, DEFNO_SLIME_, DEFNO_DIGI_, DEFDEVMETER_
  380.           public   DEFMETERFLAGS_, DEFRXSIGMIN_, DEFRXSMETER_, DEFRXDB_
  381.           public   DEFDBFLOOR_, DEFMULT1_, DEFMULT2_, DEFOFS1_, DEFOFS2_
  382.           public   DEFMULT3_, DEFMULT4_, DEFOFS3_, DEFOFS4_
  383.  
  384. DEFCAL_:  db      'G8KBB ', 6Ah         ; Call des TNC
  385. DEFIDE_:  db      'THENET'              ; Ident des TNC
  386. DEFDES_:  dw      100                   ; Laenge der Destination Liste
  387. DEFWQU_:  dw      10                    ; minimale Qualitaet fuer Autoupdate
  388. DEFCH0_:  dw      10                    ; HDLC Kanal Qualitaet
  389. DEFCH1_:  dw      255                   ; RS232 Kanal Qualitaet
  390. DEFOBC_:  dw      7                     ; Anfangswert Knotenlebensdauer
  391. DEFOBB_:  dw      5                     ; Restlebensdauer fuer Rundspruch
  392. DEFBRI_:  dw      1800                  ; Rundspruchintervall
  393. DEFTLI_:  dw      10                    ; Anfangswert Paketlebensdauer
  394. DEFTTO_:  dw      300                   ; Timeout in Level3
  395. DEFTTR_:  dw      2                     ; Versuche in Level3
  396. DEFTAC_:  dw      6                     ; Level3 Wartezeit bis ACK
  397. DEFTBS_:  dw      180                   ; Level3 Busy Wartezeit
  398. DEFTWI_:  dw      4                     ; Fenstergroesse in Level3
  399. DEFCON_:  dw      4                     ; gebufferte Frames je Verbindung
  400. DEFNOA_:  dw      900                   ; no-activity-timeout
  401. DEFPER_:  dw      64                    ; Entschlossenheit fuer Sendung frei
  402. DEFSLO_:  dw      10                    ; Zeitschlitzbreite
  403. DEFRAK_:  dw      5                     ; Level2, Timer1
  404. DEFMAF_:  dw      2                     ; Level2, Fenstergroesse
  405. DEFL2T_:  dw      10                    ; Level2, Versuche
  406. DEFLT2_:  dw      100                   ; Level2, Timer2
  407. DEFLT3_:  dw      18000                 ; Level2, Timer3
  408. DEFRPA_:  dw      0                     ; Level2 Digipeating Freigabe
  409. DEFVAL_:  dw      1                     ; Calls pruefen
  410. DEFBEA_:  dw      2                     ; Bakenmodus
  411. DEFCQ_:   dw      1                     ; CQ-Ruf erlaubt j/n
  412. DEFDPA_:  db      0                     ; Full-Duplex j/n
  413. DEFXFP_:  db      0                     ; Flags in den Pausen
  414. DEFESC_:  db      01Bh                  ; Befehlseinleitungszeichen (Host)
  415. DEFTP_:   db      30                    ; Senderverzoegerung
  416.  
  417. DEFPWD_:  db      'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789   '
  418.           db      'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789   ',0   ; Passwort
  419.  
  420. DEFINF_:  db      'SOFTWARE VON NORD><LINK Modified and ext'
  421.           db      'ended by G8KBB, East Suffolk Data Group ',0   ; Infotext
  422. ;
  423. ; Additional defaults for extended versions
  424. ;
  425. DEFCW_:   dw      1800            ; 0 = off, else period in minutes
  426. DEFCWS_:  db      6                     ; bit speed in 10's of milliseconds
  427. DEFHOS_:  db      0            ; 0 = thenet, 1 = host mode
  428. DEFKIS_:  db      0            ; 0 = crosslink, 1 2 or 3 = kiss
  429. DEFMHL_:  db      10                    ; 0 = no heard list, else list length
  430. DEFBCN_:  db      3                     ; controls which ports for nodes bcst
  431. DEFBR1_:  dw      0            ; interval for port 1 bcasts, 0=off
  432. DEFALG_:  db      0            ; node bcast algorithm selector
  433. beadil_:  db      0,0,0,0,0,0,0,0       ; optional single beacon digilist
  434. DEFBIN_:  dw      900            ; beacon interval in seconds
  435. DEFCSB_:  db      1            ; connect to host(0), BBS(1)
  436. DEFNOHASH_: db    0            ; per port bit for hash node ctrl
  437. DEFMYIPADDR_: dw  0,0            ; this node's IP address
  438. DEFIPBCAST_:  dw  0,0            ; the IP broadcast address
  439. DEFIPL2MODES_: db 0            ; per port IP L2 default modes
  440. DEFIPTTL_:    db  20            ; IP Time To Live
  441. DEFIPENABLE_: db  1            ; enable / disable IP router
  442. DEFHLP_:  db      31            ; help flags default
  443. DEF_MTU_IP0_:  dw  256            ; ip port 0 mtu
  444. DEF_MTU_IP1_:  dw  256            ; ip port 1 mtu
  445. DEF_MTU_IPN_:  dw  236            ; ip netrom port mtu
  446. DEF_MTU_I_MAX_:  dw  257        ; l2 i frame data max
  447. DEF_MTU_L2_MAX_: dw  328        ; l2 total frame size max
  448. DEFRECONNECT_:   db  1            ; reconnect on remote disconnect
  449. DEFNO_SLIME_:    db  0            ; slime trail control word
  450. DEFNO_DIGI_:     db  0            ; digipeat control word default
  451. DEFDEVMETER_:    db  0            ; deviation meter control word
  452. DEFMETERFLAGS_:  dw  27            ; meter mode and control flags
  453. DEFRXSIGMIN_:    db  50            ; s meter noise adc reading
  454. DEFRXSMETER_:    db  10            ; s meter multiplier
  455. DEFRXDB_:        db  50            ; dBm multiplier
  456. DEFDBFLOOR_:     db  120        ; dBm noise floor reading
  457. DEFMULT1_:       db  0            ; adc channel 1 multiplier
  458. DEFMULT2_:       db  0            ; adc channel 2 multiplier
  459. DEFOFS1_:        db  0            ; adc channel 1 offset
  460. DEFOFS2_:        db  0            ; adc channel 2 offset
  461. DEFMULT3_:       db  0            ; adc channel 3 multiplier
  462. DEFMULT4_:       db  0            ; adc channel 4 multiplier
  463. DEFOFS3_:        db  0            ; adc channel 3 offset
  464. DEFOFS4_:        db  0            ; adc channel 4 offset
  465.  
  466. ; +---------------------------------------------------------------------+
  467. ; |                                                                     |
  468. ; | SIO (HDLC, RS232) Initialisierungstabellen.                         |
  469. ; |                                                                     |
  470. ; +---------------------------------------------------------------------+
  471.  
  472. ;
  473. ; Mit "Pin" ist immer der SIO-Pin gemeint.
  474. ; Mit "Modemstecker" ist der RS232-Stecker gemeint - "Modem" in diesem
  475. ; Zusammenhang bezieht sich auf die Signalbezeichung, der TNC wird ja
  476. ; bei Anschluss an einen Rechner oder an ein Terminal als "Modem"
  477. ; betrieben.
  478. ;
  479.  
  480.  
  481.  
  482. ;
  483. ; SIO Kanal B, RS232 (Hostterminal oder Crosslink)
  484. ;
  485. SIBINI:   db    018h            ; WR 0 :  Channel Reset
  486.           db    2               ; WR 2 :
  487.           db    000h            ;   Interrupt Vector (Page-Anfang)
  488.           db    4               ; WR 4 :
  489.           db    044h            ;   /16 Clock, 1 Stopbit, kein Parity
  490.           db    5               ; WR 5 :
  491. SIBIW5:   db    0EAh            ;   Tx 8 Bit, Tx Enable, Pin /DTR low,
  492.                                 ;   Pin /RTS low -> Modemstecker CTS high
  493.           db    3               ; WR 3 :
  494.           db    0C1h            ;   Rx 8 Bit, Rx Enable
  495.           db    1               ; WR 1 :
  496.           db    01Fh            ;   Interrupt on all Rx Character, Status
  497.                                 ;   affects Vector, Tx Interrupt Enable,
  498.                                 ;   External/Status Interrupt Enable
  499.           db    010h            ; WR 0 :  Reset External/Status Interrupts
  500. SIBIEN:
  501.  
  502.  
  503.     public SIAINI, SIAIEN, SIAIW5, SIBIW5
  504. ;
  505. ; SIO Kanal A, HDLC (Packet-Radio-Modem)
  506. ;
  507. SIAINI:   db      018h          ; WR 0 :  Channel Reset
  508.           db      4             ; WR 4 :
  509.           db      020h          ;   /1 Clock, SDLC Mode (01111110 Flag),
  510.                                 ;   Sync Modes Enable
  511.           db      5             ; WR 5 :
  512. SIAIW5:   db      0E1h          ;   Tx 8 Bit, CCITT CRC, Tx CRC Enable,
  513.                                 ;   Pin /DTR low, Pin /RTS high -> PTT aus 
  514.           db      3             ; WR 3 :
  515. SIAIW3:   db      0D9h          ;   Rx 8 Bit, Hunt Phase, Rx CRC Enable,
  516.                                 ;   Rx Enable
  517.           db      7             ; WR 7 :
  518.           db      07Eh          ;   01111110 Flag
  519.           db      1             ; WR 1 :
  520.           db      01Bh          ;   Interrupt on all Rx Character,
  521.                                 ;   Tx Interrupt Enable,
  522.                                 ;   External/Status Interrupt Enable
  523.           db      010h          ; WR 0 :  Reset External/Status Interrupts
  524. SIAIEN:
  525.  
  526.  
  527.  
  528.  
  529.  
  530. ; +---------------------------------------------------------------------+
  531. ; |                                                                     |
  532. ; | Interrupt-Vektor-Tabelle (wird ins RAM uebertragen).                |
  533. ; |                                                                     |
  534. ; +---------------------------------------------------------------------+
  535.  
  536. ROMVEC:   dw    SIBTBE          ; SIO B (RS232) Tx Buffer Empty
  537.           dw    SIBESC          ; SIO B (RS232) External/Status Change
  538.           dw    SIBRCA          ; SIO B (RS232) Rx Character Available
  539.           dw    SIBSRC          ; SIO B (RS232) Special Receive Condition
  540.           dw    SIATBE          ; SIO A (HDLC)  Tx Buffer Empty
  541.           dw    SIAESC          ; SIO A (HDLC)  External/Status Change
  542.           dw    SIARCA          ; SIO A (HDLC)  Rx Character Available
  543.           dw    SIASRC          ; SIO A (HDLC)  Special Receive Condition
  544. ROMVEN:
  545.  
  546.  
  547.  
  548.  
  549.  
  550. ; +---------------------------------------------------------------------+
  551. ; |                                                                     |
  552. ; | Level 1 Initialisierung nach einem Reset.                           |
  553. ; |                                                                     |
  554. ; |   - Kaltstart :  Speicherausbau feststellen                         |
  555. ; |   - Stack setzen                                                    |
  556. ; |   - SIO initialisieren                                              |
  557. ; |   - Level 1 Variable setzen                                         |
  558. ; |   - Interrupts initialisieren                                       |
  559. ; |   - Interrupts erlauben                                             |
  560. ; |   - Sprung ins Hauptprogramm                                        |
  561. ; |                                                                     |
  562. ; +---------------------------------------------------------------------+
  563.  
  564.           extrn mainf_       ; C Hauptprogramm
  565.           extrn magicn_      ; im Hauptprogramm definierte Variable
  566. ;          extrn stack_       ; Stack im Hauptprogramm definiert
  567.       extrn stkend_      ; pointer to top of stack (G8KBB)
  568.           extrn l2stats_     ; pointer to l2 stats array ( G8KBB )
  569.  
  570. L1INIT:   di                    ; Interrupts verbieten fuer Initialisierung
  571.  
  572.           xor   A
  573. l1delay:  dec   A
  574.           jr    nz, l1delay
  575.  
  576.           ld    HL,(magicn_)    ; RAM ok = Warmstart, d.h.
  577.           ld    DE,MAGIC        ; Magic Number noch        
  578.           or    A               ; unveraendert,
  579.           sbc   HL,DE           ; wie ins RAM geschrieben ?
  580.           jr    Z,L1INI2        ; ja   - RAM-Bestueckung nicht testen
  581.  
  582.           ld    HL,RAMBOT+3FFFh ; nein - Ende RAM bei 16kB
  583.           ld    DE,RAMBOT+7FFFh ; Ende RAM bei 32kB
  584.           xor   A               ; 0 
  585.           ld    (HL),A          ; in beide moegliche
  586.           ld    (DE),A          ; RAM-Enden
  587.           dec   (HL)            ; oberes RAM-Ende = 0FFh
  588.           ld    A,(DE)          ; hat sich unteres RAM-Ende geaendert ?
  589.           or    A               ; (16kB-Bestueckung -> Spiegelung)
  590.           jr    NZ,L1INI1       ; ja   - es sind nur 16kB
  591.           inc   A               ; A = 1
  592.           ld    (DE),A          ; an unteres RAM-Ende
  593.           inc   (HL)            ; 0 an oberes RAM-Ende, auch gespiegelt ?
  594.           jr    NZ,L1INI1       ; ja   - andere Hardware, aber auch nur 16kB
  595.           ex    DE,HL           ; nein - 32kB RAM
  596. L1INI1:   ld    (RAMTOP),HL     ; oberste RAM-Speicherstelle merken
  597.  
  598. L1INI2:   ld    SP,(stkend_)
  599. ;          ld    SP,stack_+1     ; Stack setzen
  600.  
  601.           im    2               ; Interruptmode 2 = Vektorinterrupts
  602.           ld    A,RAMBOT>>8     ; Interrupt Vektor Page = RAM Anfang
  603.           ld    I,A
  604.           ld    HL,ROMVEC          ; Interrupt-Vektor vom ROM
  605.           ld    DE,RAMVEC          ; ins RAM
  606.           ld    BC,ROMVEN-ROMVEC   ; laden
  607.           ldir
  608.  
  609.           ld    HL,SIBINI       ; SIO B (RS232) initialisieren
  610.           ld    BC,SIBCTL or ((SIBIEN-SIBINI)<<8)
  611.           otir
  612.           in    A,(SIBCTL)      ; SIO B initialen Status holen
  613.           ld    (SIBRR0_),A      ; und merken
  614.           ld    A,(SIBIW5)      ; SIO B initialen Tx-Modus holen
  615.           ld    (SIBWR5),A      ; und merken
  616.  
  617.           ld    HL,SIAINI       ; SIO A (HDLC) initialisieren
  618.           ld    BC,SIACTL or ((SIAIEN-SIAINI)<<8)
  619.           otir
  620.           in    A,(SIACTL)      ; SIO A initialen Status holen
  621.           ld    (SIARR0),A      ; und merken
  622.           ld    A,(SIAIW5)      ; SIO A initialen Tx-Modus holen
  623.           ld    (SIAWR5),A      ; und merken
  624.  
  625.           call  HOINIT          ; Host-FiFo's initialisieren  
  626.           xor   A               ; A = 0
  627.           ld    (CRXSTA),A      ; Crosslink RX inaktiv
  628.           ld    (CTXSTA),A      ; Crosslink TX inaktiv
  629.           ld    (HRXSTA),A      ; HDLC RX ausserhalb Frame
  630.           ld    (HTXSTA),A      ; HDLC TX inaktiv
  631.           ld    (TICDIV),A      ; 1200Hz Zaehler starten
  632.           ld    (HTXWAI),A      ; HDLC Wartetimer inaktiv
  633.           ld    (CTXWAI),A      ; Crosslink Wartetimer inaktiv 
  634.           ld    (DEICNT),A      ; keine Interrupt-Verbietungsstufe
  635.  
  636.           jp    mainf_          ; ab ins Hauptprogramm
  637.  
  638.  
  639.  
  640.  
  641.  
  642. ; +---------------------------------------------------------------------+
  643. ; |                                                                     |
  644. ; | C :  BOOLEAN ishget()   "is host get"                               |
  645. ; |                                                                     |
  646. ; | TRUE   -  (HL=1, Z=0) Hostterminal an RS232 angeschlossen und       |
  647. ; |           Zeichen vom Terminal vorhanden (in RX-FIFO)               |
  648. ; |                                                                     |
  649. ; | FALSE  -  (HL=0, Z=1) Hostterminal nicht an RS232 angeschlossen     |
  650. ; |           oder kein Zeichen von Terminal vorhanden (in RX-FIFO)     |
  651. ; |                                                                     |
  652. ; | A benutzt, HL Returnwert.                                           |
  653. ; |                                                                     |
  654. ; +---------------------------------------------------------------------+
  655.  
  656.           public ishget_
  657.  
  658. ishget_:  call  ishost_         ; Hostterminal an RS232 ?
  659.           ret   Z               ; nein - dann nie frei (FALSE zurueck)
  660.           ld    HL,(HORXCC)     ; Zeichenzaehler Host-FIFO RX = 0 ?
  661.           ld    A,H
  662.           or    L
  663.           ret   Z               ; ja   - FALSE zurueck
  664.           ld    HL,1            ; nein - TRUE zurueck
  665.           ret
  666.  
  667.  
  668.  
  669.  
  670.  
  671. ; +---------------------------------------------------------------------+
  672. ; |                                                                     |
  673. ; | C :  hgetc()   "host get character"                                 |
  674. ; |                                                                     |
  675. ; | Zeichen von Hostterminal holen, falls angeschlossen und Zeichen da. |
  676. ; | Falls kein Hostterminal angeschlossen, ASCII Cancel zurueckgeben.   |
  677. ; | Falls kein Zeichen da, warten auf Zeichen.                          |
  678. ; |                                                                     |
  679. ; | A, DE benutzt, HL Returnwert.                                       |
  680. ; |                                                                     |
  681. ; +---------------------------------------------------------------------+
  682.  
  683.           public hgetc_
  684.  
  685. hgetc_:   call  ishost_         ; Hostterminal an RS232 ?
  686.           ld    A,ACAN          ; nein - ASCII CAN = "bisherige Eingabe
  687.           jr    Z,hgetc2        ;        Loeschen" zurueck
  688.           call  ishget_         ; ja   - Zeichen vom Hostterminal da ?
  689.           jr    Z,hgetc_        ; nein - auf Zeichen warten
  690.           di                    ; ja   - keine Ints (kein Zeigerzugriff)
  691.           ld    HL,(HORXCC)     ; RX-FIFO Zeichenzaehler - 1
  692.           dec   HL
  693.           ld    (HORXCC),HL
  694.           ld    HL,(HORXOP)     ; Output-Zeiger
  695.           ld    A,(HL)          ; Zeichen aus FIFO holen
  696.           inc   HL              ; Zeiger auf naechstes Zeichen
  697.           ex    DE,HL
  698.           ld    HL,HORXFI+HORXFL-1      ; Zeiger > letzte FIFO-Stelle, d.h.
  699.           or    A                       ; "FIFO Wrap Around" ?
  700.           sbc   HL,DE
  701.           jr    NC,hgetc1       ; nein -
  702.           ld    DE,HORXFI       ; ja   - Zeiger wieder auf FIFO-Anfang
  703. hgetc1:   ld    (HORXOP),DE     ; Zeiger abspeichern
  704.           ei                    ; Interrupt wieder frei
  705. hgetc2:   ld    L,A             ; Zeichen C-like zurueck = return(chr)
  706.           ld    H,0
  707.           or    A
  708.           ret                   ; das war's
  709.  
  710.  
  711.  
  712.  
  713.  
  714. ; +---------------------------------------------------------------------+
  715. ; |                                                                     |
  716. ; | C :  BOOLEAN ishput()   "is host put"                               |
  717. ; |                                                                     |
  718. ; | TRUE   -  (HL=1, Z=0) Hostterminal an RS232 angeschlossen und es    |
  719. ; |           koennen Zeichen gesendet werden an Hostterminal           |
  720. ; |           (TX-FIFO leer)                                            |
  721. ; |                                                                     |
  722. ; | FALSE  -  (HL=0, Z=1) Hostterminal nicht an RS232 angeschlossen     |
  723. ; |           oder es duerfen keine Zeichen gesendet werden an          |
  724. ; |           Hostterminal (TX-FIFO nicht leer)                         |
  725. ; |                                                                     |
  726. ; | A benutzt, HL Returnwert.                                           |
  727. ; |                                                                     |
  728. ; +---------------------------------------------------------------------+
  729.  
  730.           public ishput_
  731.  
  732. ishput_:  call  ishost_         ; Hostterminal an RS232 ?
  733.           ret   Z               ; nein - immer voll (FALSE zurueck)
  734.           ld    HL,(HOTXCC)     ; Zeichenzaehler Host-FIFO TX = 0 ?
  735.           ld    A,H
  736.           or    L
  737.           ret   Z               ; ja   - FALSE zurueck
  738.           ld    HL,1            ; nein - TRUE zurueck
  739.           ret
  740.  
  741.  
  742.  
  743.  
  744.  
  745. ; +---------------------------------------------------------------------+
  746. ; |                                                                     |
  747. ; | C :  VOID hputc(chr) char chr;   "host put character"               |
  748. ; |                                                                     |
  749. ; | Falls kein Hostterminal an RS232 angeschlossen, Zeichen chr         |
  750. ; | vergessen und Rueckgabe. Sonst Zeichen chr in den Hostterminal-     |
  751. ; | TX-FIFO schreiben, ggf. warten bis Platz im TX-FIFO.                |
  752. ; | Falls TX-FIFO leer war, wird der Interrupt-Zeichensender wieder     |
  753. ; | ange-"kickt".                                                       |
  754. ; |                                                                     |
  755. ; | A, HL, DE benutzt.                                                  |
  756. ; |                                                                     |
  757. ; +---------------------------------------------------------------------+
  758.  
  759.           public hputc_
  760.  
  761. hputc_:   call  ishost_         ; Hostterminal an RS232 ?
  762.           ret   Z               ; nein - Zeichen vergessen, Rueckgabe
  763.           ld    HL,(HOTXCC)     ; ja   - TX-FIFO voll ?
  764.           ld    DE,HOTXFL
  765.           or    A
  766.           sbc   HL,DE
  767.           jr    NC,hputc_       ; ja   - warten bis Platz im TX-FIFO
  768.           ld    HL,2            ; nein - Zeichen als C-Parameter vom Stack
  769.           add   HL,SP           ;        holen
  770.           ld    A,(HL)
  771.           di                    ; keine Ints (keine Zeigerzugriffe) 
  772.           ld    HL,(HOTXCC)     ; TX-FIFO Zeichenzaehler + 1
  773.           inc   HL
  774.           ld    (HOTXCC),HL
  775.           ld    HL,(HOTXIP)     ; Zeiger auf naechste freie Stelle im TX-FIFO
  776.           ld    (HL),A          ; Zeichen in TX-FIFO eintragen
  777.           inc   HL              ; Zeiger auf naechste freie Stelle
  778.           ex    DE,HL
  779.           ld    HL,HOTXFI+HOTXFL-1      ; Zeiger > letzte FIFO-Stelle, d.h.
  780.           or    A                       ; "FIFO Wrap Around" ?
  781.           sbc   HL,DE
  782.           jr    NC,hputc1       ; nein -
  783.           ld    DE,HOTXFI       ; ja   - Zeiger wieder auf FIFO-Anfang
  784. hputc1:   ld    (HOTXIP),DE     ; Zeiger abspeichern
  785.           in    A,(SIBCTL)      ; SIO Kanal B (RS232) Tx-Buffer leer ?
  786.           bit   2,A
  787.           call  NZ,HTXFCO       ; ja   - naechstes Zeichen aus TX-FIFO
  788.                                 ;        senden (falls sich kein Zeichen
  789.                                 ;        mehr im TX-FIFO befand, wird
  790.                                 ;        hiermit der Interrupt-Sender wieder
  791.                                 ;        ange-"kickt")
  792.           ei                    ; Interrupts wieder frei
  793.           ret                   ; das war's
  794.  
  795.  
  796.  
  797.  
  798.  
  799. ; +---------------------------------------------------------------------+
  800. ; |                                                                     |
  801. ; | C :  VOID kicktx(port)   unsigned port;                             |
  802. ; |                                                                     |
  803. ; |               port   = 0 :  HDLC-Port (Modem)                       |
  804. ; |                      = 1 :  Crosslink-Port (RS232)                  |
  805. ; |                                                                     |
  806. ; | Sender an-"kicken", d.h. wenn Kanal frei ist, Sendezyklus           |
  807. ; | einleiten, wenn Sender am Frameende des letzten Frames, dann        |
  808. ; | Sender mitteilen, dass noch weitere Frames folgen.                  |
  809. ; |                                                                     |
  810. ; | A, DE, HL benutzt.                                                  |
  811. ; |                                                                     |
  812. ; +---------------------------------------------------------------------+
  813.  
  814.           extrn Dpar_           ; 1 = Vollduplex an
  815.  
  816.           public kicktx_
  817.  
  818. kicktx_:  push  BC              ; C Stackframe-Pointer
  819.           push  IX              ; sichern
  820.           ld    HL,6            ; Zeiger auf C-Uebergabe-Parameter
  821.           add   HL,SP
  822.           ld    A,(HL)          ; Parameter LSB holen, Portnummer
  823.           or    A               ; Kommando fuer Crosslink-Port ?
  824.           jr    NZ,kickt3       ; ja   -
  825.           ld    HL,HTXSTA       ; nein - HDLC-Port
  826.           ld    A,(HL)          ; HDLC-Sender inaktiv ?
  827.           or    A
  828.           jr    Z,kickt1        ; ja   -
  829.           cp    7               ; nein - "in Frame(ende), weitere folgen" ?
  830.           jr    C,kickt9        ; ja   - TX muss nicht ange-"kickt" werden       
  831.           ld    (HL),6          ; nein - "in Frameende, weitere folgen" !
  832.           jr    Z,kickt9        ; wenn nur "in Frameende" war, reicht das 
  833.           ld    A,08h           ; sonst SIO Kanal A (HDLC) "Send Abort" um
  834.           out   (SIACTL),A      ; Flagwirklichzueende-Checkframe zu beenden
  835.           jr    kickt9          ; das war's
  836.  
  837. kickt1:   ld    A,(Dpar_)       ; Vollduplexbetrieb ?
  838.           or    A
  839.           jr    NZ,kickt2       ; ja   - keine DCD-Abfrage
  840.           ld    A,(SIARR0)      ; HDLC-Sender inaktiv, DCD (high, "1") ? 
  841.           bit   3,A
  842.           jr    Z,kickt2
  843.           inc   (HL)            ; ja   - Sendezyklus einleiten, wenn kein
  844.           jr    kickt9          ;        DCD mehr anliegt (TX-State = 1/2)
  845.  
  846. kickt2:   ld    A,1             ; nein - sofort Sendezyklus einleiten
  847.           call  HTXINI          ;        (TX-State = 3)
  848.           jr    kickt9          ;        das war's
  849.  
  850. kickt3:   call  ishost_         ; Hostterminal angeschlossen ?
  851.           jr    NZ,kickt8       ; ja   - alle Crosslink-Frames wegwerfen
  852.           ld    HL,CTXSTA       ; nein - Crosslink-Sender inaktiv ?
  853.           ld    A,(HL)
  854.           or    A
  855.           jr    Z,kickt6        ; ja   -
  856.           cp    10              ; nein - (vor-)letztes Zeichen im Sender ?
  857.           jr    NC,kickt5       ; ja   - direkt neues Frame beginnen
  858.           cp    7               ; nein - TX-State 7 der 9, "Frameende,
  859.           jr    Z,kickt4        ;        keine weiteren folgen" ?
  860.           cp    9
  861.           jr    NZ,kickt9       ; nein - da eh weitere folgen, nix noetig
  862. kickt4:   dec   (HL)            ; ja   - es reicht, dem Sender mitzuteilen,
  863.           jr    kickt9          ;        "weitere folgen" (7/9 -> 6/8)
  864.  
  865. kickt5:   call  CTXSTX          ; neues Crosslink-Frame mit ASCII STX
  866.           jr    kickt9          ; beginnen
  867.  
  868. kickt6:   ld    A,(SIBRR0_)      ; Crosslink-Sender inaktiv, Modemstecker DTR 
  869.           bit   5,A             ; high = 1 = Pin /CTS low, d.h. Kanal frei ?
  870.           jr    NZ,kickt7
  871.           inc   (HL)            ; nein - TX-State = 1/2 "Sendezyklus
  872.           jr    kickt9          ;        einleiten, wenn Kanal frei wird"
  873.  
  874. kickt7:   ld    A,1             ; ja   - Crosslink-Sender aktivieren
  875.           call  CTXINI          ;        (TX-State 1 -> 3)
  876.           jr    kickt9          ;        das war's
  877.  
  878. kickt8:   ld    HL,8101h        ; Kommando an Crosslink-TX-Buffer :
  879.           call  GETSRV          ; "alle Frames wegwerfen"
  880.  
  881. kickt9:   pop   IX              ; C Stackframe-Pointer
  882.           pop   BC              ; restaurieren
  883.           ret                   ; das war's endgueltig
  884.  
  885.  
  886.  
  887.  
  888.  
  889. ; +---------------------------------------------------------------------+
  890. ; |                                                                     |
  891. ; | C :  VOID pushtx()                                                  |
  892. ; |                                                                     |
  893. ; | Wenn HDLC-Sender auf Abfall von DCD wartet, sofort auf Sendung      |
  894. ; | gehen (wird gebraucht zur Vermeidung eines Deadlocks bei            |
  895. ; | Umschaltung in den Vollduplex-Betrieb).                             |
  896. ; |                                                                     |
  897. ; | A, DE, HL benutzt.                                                  |
  898. ; |                                                                     |
  899. ; +---------------------------------------------------------------------+
  900.  
  901.           public pushtx_
  902.  
  903. pushtx_:  push  BC              ; C Stackframe-Pointer
  904.           push  IX              ; sichern
  905.           ld    HL,HTXSTA       ; (HL setzen fuer HTXINI)
  906.           ld    A,(HL)          ; TX-State = 1 oder 2, "nachdem Port frei
  907.           or    A               ; wird, senden" ?
  908.           jr    Z,pusht1
  909.           cp    3
  910.           call  C,HTXINI        ; ja - dann Sender sofort hochfahren
  911. pusht1:   pop   IX              ; C Stackframe-Pointer
  912.           pop   BC              ; restaurieren
  913.           ret                   ; das war's
  914.  
  915.  
  916.  
  917.  
  918.  
  919. ; +---------------------------------------------------------------------+
  920. ; |                                                                     |
  921. ; | "SIO channel B Tx Buffer Empty" - Interruptservice                  |
  922. ; |                                                                     |
  923. ; | RS232 SIO TX-Buffer leer, entweder (Hostterminal angeschlossen)     |
  924. ; | Zeichen aus Hostterminal-FIFO falls nicht leer senden oder          |
  925. ; | (Crosslink an RS232) Zeichen aus Frame senden, Frameendebehandlung, |
  926. ; | DLE-Stuffing.                                                       |
  927. ; |                                                                     |
  928. ; |                                                                     |
  929. ; | Crosslink-Frameformat :                                             |
  930. ; |                                                                     |
  931. ; |   +-----+---------         ------+-----+-----+                      |
  932. ; |   | STX | info       ...         | ETX | FCS |                      |
  933. ; |   +-----+---------         ------+-----+-----+                      |
  934. ; |     02h   |                        03h   8 Bit Frame Checksumme,    |
  935. ; |           |                              nur ueber info, ohne 1.    |
  936. ; |           |                              DLE bei "Stuffing"         |
  937. ; |           |                                                         |
  938. ; |           +---> Infobytes, STX in info wird zu DLE STX    DLE = 10h |
  939. ; |                            ETX     "           DLE ETX              |
  940. ; |                            DLE     "           DLE DLE              |
  941. ; | G8KBB - modified to add KISS code driver                            |
  942. ; +---------------------------------------------------------------------+
  943.  
  944.           extrn crlmod_
  945.  
  946. SIBTBE:   ex  AF,AF'         ; Register sichern
  947.           exx
  948.           push  IX
  949.           ld    A,28h           ; SIO Kanal B (RS232) Reset Tx Int Pending
  950.           out   (SIBCTL),A
  951.           call  ishost_         ; Hostterminal an RS232 angeschlossen ?
  952.           jp    NZ,SIBT11       ; ja   -
  953.           ld    HL,CTXSTA       ; nein - Crosslink-Kanal
  954.           ld    A,(HL)          ; Crosslink-TX-State :
  955.           sub   5
  956.           jr    Z,SIBT4         ;  5: innerhalb Frame
  957.           jp    C,SIBT12        ;  0: letztes Zeichen aus SIO -> nix tun
  958.           dec   A
  959.           jr    Z,SIBT3         ;  6: Frameende, noch weitere, ETX gesendet
  960.           dec   A
  961.           jr    Z,SIBT3         ;  7: Frameende, keine weiteren, ETX gesendet
  962.           dec   A         
  963.           jr    Z,SIBT2         ;  8: Frameende, noch weitere, FCS gesendet
  964.           dec   A
  965.           jr    Z,SIBT1         ;  9: Frameende, keine weiteren, FCS gesendet
  966.           dec   A
  967.           jr    Z,SIBT1         ; 10: Sendungsende, vorletztes Zeichen fertig
  968.           dec   A
  969.           jr    z,SIBTE1
  970.           ld    (HL),5          ; 12: KISS command byte to send 
  971.           xor   A               ;     send a '0' ( ie a data ) frame
  972.           jr    SIBT9
  973. SIBTE1:   ld    (HL),0          ; 11: Sendungsende, letztes Zeichen fertig,
  974.           call  CCOFF           ;     TX inaktiv, Crosslink-"Traeger"
  975.           jp    SIBT12          ;     abschalten, das war's
  976.  
  977. SIBT1:    inc   (HL)            ; 9/10 -> 10/11, Zaehler fuer Frameende-
  978.           ld    A,(crlmod_)    ; if crosslink is KISS, do not send dummy
  979.           or    A        ; zero as it will confuse things.
  980.           jr    NZ,SIBT12
  981.           xor   A
  982.           jr    SIBT10          ; Feststellung, 00h als Dummy an RS232
  983.  
  984. SIBT2:    call  CTXSTX          ; Frameende, noch weitere :  neues Frame
  985.           jr    SIBT12          ; beginnen, das war's
  986.  
  987. SIBT3:    inc   (HL)            ; Frameende, ETX gesendet : TX-State wie
  988.           inc   (HL)            ; vorher, aber "FCS gesendet"
  989.           ld    A,(CTXFCS)      ; Frame-Checksumme
  990.           jr    SIBT10          ; aussenden
  991.  
  992. SIBT4:    ld    HL,CTXCSA       ; kommt jetzt STX/ETX/DLE nach DLE ?
  993.           ld    A,(HL)
  994.           or    A
  995.           jr    Z,SIBT5
  996.           ld    (HL),0          ; ja   - "nach DLE"-Buffer loeschen
  997.           jr    SIBT9           ;        und Zeichen aus Buffer aussenden
  998.  
  999. SIBT5:    ld    HL,0100h        ; nein - Kommando :  "naechstes Zeichen aus
  1000.           call  GETSRV          ; TX-Crosslink-Buffer holen" ausfuehren
  1001.           ld    A,L             ; Frame zuende ?
  1002.           bit   7,H
  1003.           jr    Z,SIBT7         ; nein - normales Zeichen
  1004.           ld    HL,CTXSTA       ; ja   - TX-State "Frameende, weitere folgen"
  1005.           inc   (HL)
  1006.           bit   0,A             ; noch weitere Frames vorhanden ?
  1007.           jr    Z,SIBT6
  1008.           inc   (HL)            ; nein - TX-State "Frameende, keine weiteren"
  1009. SIBT6:    ld    A,(crlmod_)      ; check for KISS mode
  1010.           or    A
  1011.           jr    NZ,SIBT61       ; jump if KISS
  1012.           ld    A,AETX          ; Frame mit ETX beenden
  1013.           jr    SIBT10
  1014. SIBT61:   ld    A,FEND          ; Send a KISS FRAME END char
  1015.           inc   (HL)
  1016.           inc   (HL)            ; skip over the checksum state for KISS
  1017.           jr    SIBT10
  1018.  
  1019. SIBT7:    ld    B,A             ; save char in B reg while checking for KISS
  1020.           ld    A,(crlmod_)
  1021.           or    A
  1022.           ld    A,B             ; reinstate char
  1023.           jr    Z,SIBT71        ; jump if crosslink rather than KISS
  1024.           cp    FEND
  1025.           jr    NZ,SIBT7a       ; check for FEND character within the frame
  1026.           ld    A,TFEND         ; replace FEND with FESC,TFEND
  1027.           jr    SIBT7b
  1028. SIBT7a:   cp    FESC            ; check for FESC character within frame
  1029.           jr    NZ,SIBT9        ; go send char if it isn't
  1030.           ld    A,TFESC         ; replace FESC with FESC,TFESC
  1031. SIBT7b:   ld    (CTXCSA),A
  1032.           ld    A,FESC
  1033.           jr    SIBT10
  1034. SIBT71:   cp    ASTX            ; auszusendendes Zeichen STX/ETX/DLE ?
  1035.           jr    Z,SIBT8
  1036.           cp    AETX
  1037.           jr    Z,SIBT8
  1038.           cp    ADLE
  1039.           jr    NZ,SIBT9
  1040. SIBT8:    ld    (CTXCSA),A      ; ja   - entsprechendes Zeichen merken
  1041.           ld    A,ADLE          ;        und DLE aussenden
  1042.           jr    SIBT10
  1043.  
  1044. SIBT9:    ld    C,A             ; nein - Zeichen merken
  1045.           ld    HL,CTXFCS       ;        Checksumme := Checksumme + Zeichen
  1046.           add   A,(HL)
  1047.           ld    (HL),A
  1048.           ld    A,C             ;        Zeichen restaurieren und senden
  1049.  
  1050. SIBT10:   out   (SIBDAT),A      ; Zeichen an SIO ausgeben
  1051.           jr    SIBT12          ; das war's
  1052.  
  1053. SIBT11:   call  HTXFCO          ; Zeichen aus Hostterminal-Buffer an RS232
  1054.  
  1055. SIBT12:   pop   IX              ; Register restaurieren
  1056.           exx
  1057.           ex   AF,AF'
  1058.           ei                    ; Interrupts wieder erlauben
  1059.           reti                  ; das war's
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065. ; +---------------------------------------------------------------------+
  1066. ; |                                                                     |
  1067. ; | "SIO channel B External Status Change" - Interruptservice           |
  1068. ; |                                                                     |
  1069. ; | RS232 DCD Wechsel                                                   |
  1070. ; |   DCD ist das Crosslink/Hostterminal-Signal. Ein Wechsel bedeutet   |
  1071. ; |   Umschaltung von Hostterminal auf Crosslink oder umgekehrt. Es     |
  1072. ; |   werden alle Buffer, FIFO's und Variable fuer Crosslink und        |
  1073. ; |   Hostterminal initialisiert. Noch nicht verarbeitete Inhalte       |
  1074. ; |   werden weggeworfen. Ggf. wird der Crosslink-"Vorlauftraeger"      |
  1075. ; |   abgeschaltet.                                                     |
  1076. ; |                                                                     |
  1077. ; | SIO Pin /CTS = RS232 Modemstecker DTR Wechsel                       |
  1078. ; |   Dies ist das Crosslink-Kanal-"DCD". Ein Wechsel bedeutet den      |
  1079. ; |   Wechsel von einem freien auf einen belegten Kanal oder umgekehrt. |
  1080. ; |   Geschieht ein Wechsel von besetzt auf frei und der Sender wartete |
  1081. ; |   auf freien Kanal, dann wird entsprechend die Sendesequenz         |
  1082. ; |   aktiviert ("Vorlauftraeger" oder "Async"-WAIT").                  |
  1083. ; |   Geschieht ein Wechsel von frei auf besetzt und der Sender befand  |
  1084. ; |   sich im "Async"-WAIT Warten oder im "Vorlauftraeger", dann wird   |
  1085. ; |   die Sendesequenz abgebrochen und wieder auf Warten auf freien     |
  1086. ; |   Kanal gesetzt, ggf. wird der Crosslink-"Vorlauftraeger"           |
  1087. ; |   abgeschaltet.                                                     |
  1088. ; |                                                                     |
  1089. ; | 1200 Hz SIO Pin SYNC Flanken                                        |
  1090. ; |   Dies ist der grundlegende Timer-Interrupt. Hieraus wird der       |
  1091. ; |   System-10-msec-Takt abgeleitet. Der Systemtimer wird aufgerufen   |
  1092. ; |   und die Senderwartevariablen werden verwaltet. Bei Ablauf wird    |
  1093. ; |   entsprechend der Sendesequenz verfahren.                          |
  1094. ; |                                                                     |
  1095. ; +---------------------------------------------------------------------+
  1096.  
  1097.           extrn timer_       ; C Systemtimer (10 msec)
  1098.           extrn hststs_      ; host mode status register
  1099.           extrn hstmod_      ; host mode flag
  1100.           extrn hotout_      ; host mode timeout counter
  1101.  
  1102. SIBESC:   ex  AF,AF'         ; Register sichern
  1103.           exx
  1104.           push  IX
  1105.           in    A,(SIBCTL)      ; Status SIO Kanal B (RS232) holen
  1106.           ld    B,A             ; und merken
  1107.           ld    A,10H           ; Reset External/Status Interrupts
  1108.           out   (SIBCTL),A
  1109.           ld    HL,SIBRR0_
  1110.           ld    A,(HL)          ; alter Status
  1111.           ld    (HL),B          ; neuen Status merken
  1112.           xor   B
  1113.           ld    C,A             ; C = was hat sich geaendert
  1114.           bit   3,C             ; Abfrage DCD-Wechsel-Interrupt
  1115.           jr    Z,SIBE1
  1116.  
  1117. ;
  1118. ; DCD hat sich geaendert
  1119. ;  
  1120.           push  BC              ; Status/Statusaenderung merken
  1121.           call  HOINIT          ; Hostterminal-FIFO's loeschen,
  1122.                                 ; Crosslink-"Traeger" aus
  1123.           ld    BC,8101h        ; aktive Crosslink-TX-Buffer in
  1124.           call  PUTSRV          ; "Gesendet"-Liste einhaengen
  1125.           ld    HL,8101h        ; aktive Crosslink-RX-Buffer
  1126.           call  GETSRV          ; auf den Muell werfen
  1127.           xor   A               ; Crosslink RX/TX Variable resetten
  1128.           ld    (CRXSTA),A
  1129.           ld    (CTXSTA),A
  1130.           ld    (CTXWAI),A
  1131.           pop   BC              ; Status/Statusaenderung restaurieren
  1132.  
  1133. SIBE1:    bit   5,C             ; Abfrage CTS-Wechsel-Interrupt
  1134.           jr    Z,SIBE5
  1135.  
  1136. ;
  1137. ; Pin /CTS = Modemstecker DTR hat sich geaendert
  1138. ; (Crosslink-"Traeger" Input)
  1139. ;
  1140.           push  BC              ; Status/Statusaenderung merken
  1141.           bit   3,B             ; check to see if crosslink or host
  1142.           jr    Z,SIBE20        ; if crosslink, go do old code
  1143.           ld    A,(hstmod_)     ; else check if host mode enabled
  1144.           or    A
  1145.           jr    NZ,SIBE2H       ; If so, go handle host mode CTS change
  1146. SIBE20:   ld    HL,CTXSTA
  1147.           ld    A,(HL)          ; Pin /CTS low = Modemstecker DTR high =
  1148.           bit   5,B             ; Crosslink-Kanal frei zur Sendung ?
  1149.           jr    Z,SIBE2         ; nein - ging also von frei auf besetzt
  1150.           or    A               ; ja   - Crosslink-TX inaktiv ?
  1151.           jr    Z,SIBE4         ; ja   - nix weiter tun
  1152.           cp    3               ; nein - auf "Kanal frei" wartend ?
  1153.           jr    NC,SIBE4        ; nein - TX muss nicht aktiviert werden
  1154.           call  CTXINI          ; ja   - Crosslink-Sendesequenz aktivieren
  1155.           jr    SIBE4
  1156.  
  1157. SIBE2H:   ld    HL,hststs_      ; point to state parameter for host mode
  1158.           ld    A,(HL)          ; switch on state.....
  1159.           or    A
  1160.           jr    Z,SIBEH0        ; state 0
  1161.           dec   A
  1162.           jr    Z,SIBEH1        ; state 1
  1163.           dec   A
  1164.           jr    Z,SIBEH2        ; state 2
  1165.           dec   A
  1166.           jr    Z,SIBEH3        ; state 3
  1167.           dec   A
  1168.           jr    NZ,SIBE4        ; state 4 - drop thru rather than jump
  1169.           bit   5,B             ; 4:
  1170.           jr    NZ,SIBE4        ; check if DTR true - jump if not
  1171.           ld    (HL),3          ; set to state 3
  1172.           call  dropdcd_        ; drop DCD
  1173.           ld    A,20
  1174.           ld    (hotout_),A     ; timeout 20 seconds
  1175.           jr    SIBE4
  1176. SIBEH0:   bit   5,B             ; 0:
  1177.           jr    NZ,SIBE4        ; check if DTR true - jump if not
  1178.           ld    (HL),5          ; set to state 5
  1179.           call  raisedcd_       ; raise DCD
  1180.           jr    SIBE4
  1181. SIBEH1:   bit   5,B             ; 1:
  1182.           jr    NZ,SIBE4        ; check if DTR true - jump if not
  1183.           ld    (HL),2          ; set to state 2
  1184.           jr    SIBE4
  1185. SIBEH2:   bit   5,B             ; 2:
  1186.           jr    Z,SIBE4         ; check if DTR true - jump if it is
  1187.           ld    (HL),7          ; set to state 7
  1188.           jr    SIBE4
  1189. SIBEH3:   bit   5,B             ; 3:
  1190.           jr    Z,SIBE4         ; check if DTR true - jump if it is
  1191.           ld    (HL),0          ; set to state 0
  1192.           jr    SIBE4
  1193.  
  1194. SIBE2:    sub   3               ; Crosslink-Kanal frei -> besetzt,
  1195.           jr    Z,SIBE3         ; "Async"-WAIT Wartezustand (State 3)
  1196.           dec   A               ; oder Crosslink-"Vorlauftraeger" (State 4) ? 
  1197.           jr    NZ,SIBE4        ; nein - nix weiter tun
  1198. SIBE3:    ld    (CTXWAI),A      ; ja   - Wartezaehler inaktivieren ( = 0),
  1199.           dec   (HL)            ;        TX-Wartezustand wieder auf Zustand
  1200.           dec   (HL)            ;        vor Warten/"Vorlauftraeger"
  1201.           bit   1,(HL)          ;        war es "Vorlauftraeger" (4-2=2) ?
  1202.           call  NZ,CCOFF        ;        ja - diesen abschalten
  1203.  
  1204. SIBE4:    pop   BC              ; Status/Statusaenderung restaurieren
  1205.  
  1206.  
  1207. SIBE5:    bit   4,C             ; Abfrage SYNC-Flanken-Interrupt
  1208.           jr    Z,SIBE9
  1209.  
  1210. ;
  1211. ; Flanke am Pin SYNC = 1200 Hz Interrupt
  1212. ;
  1213.           ld    HL,CTXWAI       ; Crosslink TX-Wartezaehler inaktiv ?
  1214.           ld    A,(HL)
  1215.           or    A
  1216.           jr    Z,SIBE7         ; ja   -
  1217.           dec   (HL)            ; nein - abgelaufen ?
  1218.           jr    NZ,SIBE7        ; nein -
  1219.           ld    HL,CTXSTA       ; ja   - war es "Vorlauftraeger" (State 4) ?
  1220.           ld    A,(HL)
  1221.           cp    4
  1222.           jr    Z,SIBE6
  1223.           inc   (HL)            ; nein - war "Async"-WAIT, ab jetzt 2,5 msec
  1224.           call  CTXPRE          ;        Crosslink-"Vorlauftraeger" (State 4)
  1225.           jr    SIBE7
  1226. SIBE6:    call  CTXSTX          ; ja   - Frame beginnen
  1227.  
  1228. SIBE7:    ld    HL,TICDIV       ; 1200 Hz -> 10 msec Teiler abgelaufen ?
  1229.           inc   (HL)
  1230.           ld    A,(HL)
  1231.           cp    12
  1232.           jr    C,SIBE9         ; nein - dann war's das
  1233.  
  1234. ;
  1235. ; alle 10 msec :
  1236. ;
  1237.           ld    (HL),0          ; ja   - Teiler neu aktivieren
  1238.           call  timer_          ; 10 msec Ticker im Hauptprogamm          
  1239.           ld    HL,HTXWAI       ; HDLC-TX-Wartezaehler aktiv ?
  1240.           ld    A,(HL)
  1241.           or    A
  1242.           jr    Z,SIBE9         ; nein - dann war's das
  1243.           dec   (HL)            ; ja   - abgelaufen ?
  1244.           jr    NZ,SIBE9        ; nein - dann war's das
  1245.           ld    HL,HTXSTA       ; ja   - in TXDELAY ?
  1246.           ld    A,(HL)
  1247.           cp    4
  1248.           jr    Z,SIBE8         ;        ja   - Frame beginnen
  1249.           dec   A               ;        nein - TX-Statezaehler fuer HTXINI
  1250.           dec   A               ;               korrigieren und Sender
  1251.           call  HTXINI          ;               hochfahren
  1252.           jr    SIBE9
  1253.  
  1254. SIBE8:    inc   (HL)
  1255.           call  HTXSOF          ; ja   - Frame beginnen
  1256.  
  1257. SIBE9:    pop   IX              ; Register restaurieren
  1258.           exx
  1259.           ex   AF,AF'
  1260.           ei                    ; Interrupts wieder erlauben
  1261.           reti                  ; das war's
  1262.  
  1263.  
  1264.  
  1265.  
  1266.  
  1267. ; +---------------------------------------------------------------------+
  1268. ; |                                                                     |
  1269. ; | "SIO channel B Rx Character Available" - Interruptservice           |
  1270. ; |                                                                     |
  1271. ; | RS232 SIO RX Zeichen da, entweder (Hostterminal angeschlossen)      |
  1272. ; | Zeichen in den Hostterminal-FIFO schreiben falls nicht voll, oder   |
  1273. ; | (Crosslink an RS232) Zeichen in Crosslink-Buffer schreiben,         |
  1274. ; | Frameendebehandlung, DLE-Stuffing.                                  |
  1275. ; |                                                                     |
  1276. ; +---------------------------------------------------------------------+
  1277.  
  1278. SIBRCA:   ex  AF,AF'         ; Register sichern
  1279.           exx
  1280.           push  IX
  1281.           in    A,(SIBDAT)      ; Zeichen von RS232 holen
  1282.           ld    C,A
  1283.           call  ishost_         ; Hostterminal angeschlossen ?
  1284.           jp    NZ,SIBR8        ; ja   -
  1285.  
  1286. ;
  1287. ; Crosslink an RS232
  1288. ;
  1289.           ld    HL,CRXSTA       ; nein - Crosslink
  1290.           ld    A,(HL)          ; Crosslink-RX-State :
  1291.           or    A
  1292.           jr    Z,SIBR1         ;  0: RX inaktiv
  1293.           dec   A
  1294.           jr    Z,SIBR3         ;  1: RX aktiv, innerhalb Frame
  1295.           dec   A
  1296.           jr    Z,SIBR5         ;  2: RX aktiv, letztes Zeichen war DLE
  1297.           dec   A
  1298.           jr    nz,SIBR11       ;  4: KISS ignore command byte
  1299.           ld    (HL),0          ;  3: Frameende, Checksumme kommt, (3 -> 0)
  1300.           ld    A,(CRXFCS)      ; RX Checksumme ok ?
  1301.           cp    C
  1302.           ld    BC,8100h        ; (Befehl "Crosslink-RX-Buffer in RX-Liste")
  1303.           jr    Z,SIBR7         ; ja   - Frame ok, in RX-Liste einhaengen
  1304.           inc   C               ; (Befehl "Crosslink-RX-Buffer auf Muell)
  1305.           ld    HL,(l2stats_+82)
  1306.           inc   HL              ; bump checksum error l2stats[10][1]
  1307.           ld    (l2stats_+82),HL
  1308.           jr    SIBR7           ; nein - Framebuffer auf den Muell werfen
  1309.  
  1310. SIBR1:    ld    A,(crlmod_)     ; check if in KISS mode
  1311.           or    A
  1312.           ld    A,C             ; RX inaktiv,
  1313.           jr    Z,SIBR1a        ; if not KISS, jump
  1314.           cp    FEND            ; if KISS, check for FEND character at start
  1315.           jp    NZ,SIBR10
  1316.           ld    (HL),4          ; then go to mode 4 to ignore command byte
  1317.           jr    SIBR2
  1318. SIBR1a:   cp    ASTX            ; Zeichen = Frameanfang (STX) ? 
  1319.           jp    NZ,SIBR10       ; nein - dann war's das
  1320.           inc   (HL)            ; ja   - RX-State "RX innerhalb Frame" (1)
  1321. SIBR2:    xor   A               ;        RX-Checksumme loeschen
  1322.           ld    (CRXFCS),A
  1323.           ld    BC,8101h        ;        neuen Crosslink-RX-Buffer beginnen
  1324.           jr    SIBR7           ;        das war's
  1325.  
  1326. SIBR3:    ld    A,(crlmod_)     ; check for KISS mode
  1327.           or    A
  1328.           ld    A,C             ; RX aktiv, innerhalb Frame,
  1329.           jr    Z,SIBR3a        ; jump for non KISS
  1330.           cp    FEND
  1331.           jr    Z,SIBR40        ; end of frame detected
  1332.           cp    FESC
  1333.           jr    Z,SIBR4         ; KISS frame escape character
  1334.           jr    SIBR6
  1335. SIBR3a:   cp    ASTX            ; Zeichen = Frameanfang (STX) ?
  1336.           jr    Z,SIBR2         ; ja   - RX resetten, neues Frame
  1337.           cp    ADLE            ; Zeichen DLE ?
  1338.           jr    Z,SIBR4         ; ja   - RX-State "letztes Zeichen DLE" (2)
  1339.           cp    AETX            ; nein - Zeichen = Frameende (ETX) ?
  1340.           jr    NZ,SIBR6        ; nein - normales Info-Zeichen
  1341.           inc   (HL)            ; ja   - RX-State "Checksumme kommt" (3)
  1342. SIBR4:    inc   (HL)
  1343.           jr    SIBR10          ; das war's
  1344.  
  1345. SIBR40:   ld    (hl),0          ; KISS end of frame
  1346.           ld    BC,8100h        ; no checksum - just valid data !
  1347.           jr    SIBR7           ; so go to it !
  1348.  
  1349. SIBR5:    ld    A,(crlmod_)
  1350.           or    A
  1351.           jr    Z,SIBR5b        ; jump if not KISS mode
  1352.           ld    A,C             ; get received character to replace
  1353.           cp    TFESC           ; replace shifted ESC by ESC
  1354.           jr    NZ,SIBR5a
  1355.           ld    C,FESC
  1356.           jr    SIBR5b
  1357. SIBR5a:   cp    TFEND           ; replace shifted END by END
  1358.           jr    NZ,SIBR5b
  1359.           ld    C,FEND
  1360. SIBR5b:   dec   (HL)            ; letztes Zeichen war DLE, naechstes Zeichen
  1361.                                 ; (STX/ETX/DLE) ist Info, RX-State 2 -> 1
  1362. SIBR6:    ld    HL,CRXFCS       ; Info-Zeichen
  1363.           ld    A,(HL)          ; auf Checksumme
  1364.           add   A,C             ; addieren
  1365.           ld    (HL),A
  1366.           ld    B,0001h         ; und in Crosslink-RX-Buffer
  1367. SIBR7:    call  PUTSRV          ; Crosslink-RX-Buffer-Verwaltung
  1368.           jr    SIBR10          ; das war's
  1369.  
  1370. SIBR11:   ld    A,C             ; KISS - ignore command byte
  1371.           cp    FEND            ; unless it is an END byte
  1372.           jr    Z,SIBR2
  1373.           ld    (HL),1
  1374.           jr    SIBR10
  1375.  
  1376. ;
  1377. ; Hostterminal an RS232
  1378. ;
  1379. SIBR8:    ld    HL,HORXFL       ; noch Platz im RX-Hostterminal-FIFO, d.h.
  1380.           ld    DE,(HORXCC)     ; Zeichenzaehler + 1 <= FIFO-Laenge ?
  1381.           inc   DE
  1382.           or    A
  1383.           sbc   HL,DE
  1384.           jr    C,SIBR10        ; nein - Zeichen vergessen
  1385.           ld    (HORXCC),DE     ; ja   - Zeichenzaehler + 1 abspeichern
  1386.           ld    HL,(HORXIP)     ; Zeiger auf naechste freie Stelle
  1387.           ld    (HL),C          ; Zeichen in den FIFO einschreiben
  1388.           inc   HL              ; Zeiger auf naechste Stelle
  1389.           ex    DE,HL
  1390.           ld    HL,HORXFI+HORXFL-1      ; Zeiger > letzte FIFO-Stelle, d.h.
  1391.           or    A                       ; "FIFO Wrap Around" ?
  1392.           sbc   HL,DE
  1393.           jr    NC,SIBR9        ; nein -
  1394.           ld    DE,HORXFI       ; ja   - Zeiger auf FIFO-Anfang
  1395. SIBR9:    ld    (HORXIP),DE     ; Zeiger abspeichern
  1396.  
  1397. SIBR10:   pop   IX              ; Register restaurieren
  1398.           exx
  1399.           ex   AF,AF'
  1400.           ei                    ; Interrupts wieder erlauben
  1401.           reti                  ; das war's
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407. ; +---------------------------------------------------------------------+
  1408. ; |                                                                     |
  1409. ; | "SIO channel B Special Receive Condition" - Interruptservice        |
  1410. ; |                                                                     |
  1411. ; | RS232-Fehlerbedingung ruecksetzen. Nicht auswerten - Fehler ist     |
  1412. ; | Fehler und im Kommunikationsablauf passiert nix (Crosslink-Frame    |
  1413. ; | ist eh kaputt, und wen interessierts am Hostterminal,  w a s        |
  1414. ; | passiert ist).                                                      |
  1415. ; |                                                                     |
  1416. ; +---------------------------------------------------------------------+
  1417.  
  1418. SIBSRC:   push  AF              ; benutztes Register sichern
  1419.           push  HL
  1420.           ld    A,1
  1421.           out   (SIBCTL), A     ; Read register 1 ( special recv codes )
  1422.           in    A,(SIBCTL)
  1423.           push  AF              ; preserve AF whilst resetting error flag
  1424.           ld    A,30h           ; SIO Kanal B (RS232) Error Reset
  1425.           out   (SIBCTL),A      ; (Achselzucken. Kann ja nix passieren.)
  1426.           pop   AF              ; reinstate register 1
  1427.           bit   6,A             ; check for framing error
  1428.           jr    NZ,SIBSR1       ; go bump count if there is
  1429.           bit   5,A             ; check for overrun error
  1430.           jr    Z,SIBSR0        ; skip on if no error
  1431. SIBSR1:   ld    HL,(l2stats_+66)
  1432.           inc   HL              ; bump error count l2stats[8][1]
  1433.           ld    (l2stats_+66),HL
  1434. SIBSR0:   pop   HL
  1435.           pop   AF              ; benutztes Register restaurieren
  1436.           ei                    ; Interrupts wieder erlauben
  1437.           reti                  ; das war's
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443. ; +---------------------------------------------------------------------+
  1444. ; |                                                                     |
  1445. ; | "SIO channel A Tx Buffer Empty" - Interruptservice                  |
  1446. ; |                                                                     |
  1447. ; | HDLC SIO TX-Buffer leer, naechstes Zeichen aus HDLC-TX-Framebuffer  |
  1448. ; | holen und senden, wenn innerhalb Frame. Bei Frameende ohne Zeichen- |
  1449. ; | ausgabe in den Underrun/EoM-Interrupt laufen lassen.                |
  1450. ; | Nach einem Underrun/EoM-Interrupt entweder neues Frame beginnen     |
  1451. ; | (es sind noch weitere vorhanden) oder Dummyframe zur Feststellung   |
  1452. ; | des Endes des vorherigen Frames beginnen (keine weiteren mehr       |
  1453. ; | vorhanden). Nachdem ueber das Dummyframe Ende (Flag von vorherigem  |
  1454. ; | Frame hat SIO verlassen) des vorherigen Frames festgestellt wurde,  |
  1455. ; | Sender abschalten.                                                  |
  1456. ; |                                                                     |
  1457. ; +---------------------------------------------------------------------+
  1458.  
  1459.           extrn cwstate_, cwkick
  1460.           extrn xFpar_          ; 1 = Flags in Pausen senden, 0 sonst
  1461.  
  1462. SIATBE:   ex  AF,AF'         ; Register sichern
  1463.           exx
  1464.           push  IX
  1465.           ld    A,28h           ; SIO Kanal A (HDLC) Reset TX Int Pending
  1466.           out   (SIACTL),A
  1467.           ld    HL,HTXSTA       ; HDLC-TX innerhalb Frame Datenbytes ?
  1468.           ld    A,(HL)
  1469.           sub   5
  1470.           jr    NZ,SIAT1        ; nein -
  1471.           ld    L,A             ; ja   - Zeichen aus HDLC-TX-Framebuffer
  1472.           ld    H,A             ; (HL=0) holen in HL
  1473.           call  GETSRV
  1474.           ld    A,L             ; Zeichen in A
  1475.           bit   7,H             ; Frame zueende ?
  1476.           jr    Z,SIAT4         ; nein - Zeichen an HDLC-Port ausgeben
  1477.           ld    HL,HTXSTA       ; ja   - TX-State "Frameende, weitere folgen"
  1478.           inc   (HL)
  1479.           bit   0,A             ; folgen noch weitere Frames ?
  1480.           jr    Z,SIAT5         ; ja   - dann war's das (ab in Underrum/EoM)
  1481.           inc   (HL)            ; nein - TX-State "Frameende, keine weiteren"
  1482.           jr    SIAT5           ; das war's dann (ab in Underrun/EoM)
  1483.  
  1484. SIAT1:    dec   A               ; TX-State 6 "Frameende, weitere folgen" ?
  1485.           jr    NZ,SIAT2
  1486.           dec   (HL)            ; ja   - TX-State 6 -> 5, "Innerhalb Frame",
  1487.           call  HTXSOF          ;        neues Frame beginnen
  1488.           jr    SIAT5           ;        das war's
  1489.  
  1490. SIAT2:    dec   A               ; nein - TX-State :
  1491.           jr    Z,SIAT3         ;  7: 1. CRC-Byte gesendet, TX-State 7 -> 8,
  1492.                                 ;     Dummyframe zur Feststellung des
  1493.                                 ;     sicheren Endes des vorherigen Frames 
  1494.                                 ;     mit 00h beginnen
  1495.           dec   A
  1496.           jr    Z,SIAT3         ;  8: CRC verlaesst SIO, TX-State 8 -> 9,
  1497.                                 ;     00h an Dummyframe
  1498.           dec   A
  1499.           jr    Z,SIAT3         ;  9: Flag verlaesst SIO, TX-State 9 -> 10,
  1500.                                 ;     00h an Dummyframe
  1501.           dec   A
  1502.           jr    NZ,SIAT5        ; <5: -> ignorieren (Dummyframeende)
  1503. ; cwstarts here
  1504.           ld    A,(cwstate_)    ; if CW state is '-1', it is waiting to start
  1505.           inc    A        ; so if it is, and if we are in state 10, then
  1506.           jr    NZ, SIAT2b    ; call cwkick in order to send cwid tacked on
  1507. SIAT2c:   call  cwkick        ; to the end of the current transmission.
  1508.           jr    SIAT5
  1509. SIAT2b:   inc   A        ; check also if calibrate is waiting to start
  1510.           jr    Z,SIAT2c    ; if so, then go kick it into action
  1511.           xor   A
  1512. ; end of cw code link
  1513.           ld    (HL),A          ; 10: Flag komplett gesendet,
  1514.                                 ;     TX-State 10 -> 0, Sender abschalten
  1515.           ld    A,5             ;     Pin /RTS high = Ptt aus, TX Disable
  1516.           out   (SIACTL),A
  1517.           ld    HL,SIAWR5
  1518.           res   1,(HL)
  1519.           ld    A,(xFpar_)      ;     ( Flags in Pausen ein ?              )
  1520.           or    A
  1521.           jr    NZ,SIAT2a       ;     ( ja   - SIO-TX eingeschaltet lassen )
  1522.           res   3,(HL)          ;     ( nein - SIO-TX ausschalten          )
  1523. SIAT2a:   ld    A,(HL)
  1524.           out   (SIACTL),A      ;     neuen Sendemodus merken
  1525.           ld    A,(Dpar_)       ;     Vollduplex an ?
  1526.           or    A
  1527.           call  Z,HRXRES        ;     nein - HDLC-RX resetten = einschalten
  1528.           jr    SIAT5           ;     das war's
  1529.  
  1530. SIAT3:    inc   (HL)            ; naechster TX-State
  1531. SIAT4:    out   (SIADAT),A      ; Zeichen an SIO
  1532. SIAT5:    pop   IX              ; Register restaurieren
  1533.           exx
  1534.           ex   AF,AF'
  1535.           ei                    ; Interrupts wieder erlauben
  1536.           reti                  ; das war's
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542. ; +---------------------------------------------------------------------+
  1543. ; |                                                                     |
  1544. ; | "SIO channel A External Status Change" - Interruptservice           |
  1545. ; |                                                                     |
  1546. ; | Falls Sender aus und Frameabort empfangen, HDLC-RX resetten, gerade |
  1547. ; | aktives Frame auf den Muell.                                        |
  1548. ; |                                                                     |
  1549. ; | Falls HDLC-TX-Underrun, Frame Abort senden und Frame noch einmal    |
  1550. ; | senden.                                                             |
  1551. ; |                                                                     |
  1552. ; | Falls DCD von an auf aus gewechselt hat und sich Sender in Zustand  |
  1553. ; | "nach DCD aus leite Sendesequenz oder WAIT-Warten ein" befindet,    |
  1554. ; | die naechste Sequenz entsprechend einleiten.                        |
  1555. ; |                                                                     |
  1556. ; | Falls DCD von aus auf an gewechselt hat und sich der Sender in      |
  1557. ; | WAIT-Warte-Sequenz befindet, dann WAIT-Warten abbrechen und nach    |
  1558. ; | naechstem Wechsel an auf aus wieder neu von vorne.                  |
  1559. ; |                                                                     |
  1560. ; +---------------------------------------------------------------------+
  1561.  
  1562. SIAESC:   ex  AF,AF'         ; Register sichern
  1563.           exx
  1564.           push  IX
  1565.           ld    A,10h           ; SIO Kanal A (HDLC) Reset External/Status
  1566.           out   (SIACTL),A      ; Interrupts
  1567.           in    A,(SIACTL)      ; neuen Status holen
  1568.           ld    B,A             ; B = neuer Status
  1569.           ld    HL,SIARR0
  1570.           ld    A,(HL)          ; alten Status holen
  1571.           ld    (HL),B          ; neuen Status merken
  1572.           xor   B               ; C = was hat sich geaendert ?
  1573.           ld    C,A
  1574.           ld    HL,HTXSTA       ; TX innerhalb Frame Datenbytes ?
  1575.           ld    A,(HL)
  1576.           cp    5
  1577.           jr    NZ,SIAE1        ; nein -
  1578.           bit   6,B             ; ja   - TX-Underrun ?
  1579.           jr    Z,SIAE1         ; nein - war wohl DCD-Wechsel
  1580.           push  AF
  1581.           push  BC
  1582.           push  HL
  1583.           ld    A,08h           ; ja   - Programm nicht schnell genug, Frame
  1584.           out   (SIACTL),A      ;        "ordentlich" mit Abort beenden,
  1585.           ld    (HL),6          ;        TX-State "letztes Byte aus Frame
  1586.                                 ;        gesendet, weitere Frames folgen",
  1587.           ld    HL,8000h        ;        aktuellen HDLC-TX-Framebuffer 
  1588.           call  GETSRV          ;        "rewinden" = Frame gleich noch
  1589.           ld    HL,(l2stats_+72)
  1590.           inc   HL              ; increment underrun count l2stats[9][0]
  1591.           ld    (l2stats_+72),HL
  1592.           pop   HL              ;        einmal probieren
  1593.           pop   BC
  1594.           pop   AF
  1595.  
  1596. SIAE1:    bit   3,C             ; hat DCD gewechselt ?
  1597.           jr    Z,SIAE4         ; nein - dann kann es RX Abort sein
  1598.           push  BC              ; Status sichern
  1599.           bit   3,B             ; DCD angegangen ?
  1600.           jr    NZ,SIAE2        ; ja   -
  1601.           or    A               ; nein - DCD ausgegangen - Sender inaktiv ?
  1602.           jr    Z,SIAE3         ; ja   - DCD-Wechsel ignorieren
  1603.           cp    3               ; nein - TX-State 1 oder 2,
  1604.                                 ;        "TX-Sequenz bei DCD aus einleiten" ? 
  1605.           jr    NC,SIAE3        ; nein - DCD-Wechsel ignorieren
  1606.           call  HTXINI          ; ja   - Sendesequenz einleiten
  1607.           jr    SIAE3
  1608.  
  1609. SIAE2:    cp    3               ; DCD angegangen, waehrend "WAIT abwarten" ?
  1610.           jr    NZ,SIAE3        ; nein - DCD-Wechsel ignorieren
  1611.           ld    A,(Dpar_)       ; ja   - Vollduplex an ?
  1612.           or    A
  1613.           jr    NZ,SIAE3        ; ja   - DCD ignorieren
  1614.           ld    (HL),1          ; nein - Spiel von vorn, TX-State "nachdem
  1615.                                 ;        DCD aus WAIT-Sequenz einleiten",
  1616.           xor   A               ;        Wartezaehler inaktivieren
  1617.           ld    (HTXWAI),A
  1618. SIAE3:    pop   BC              ; Status restaurieren
  1619.  
  1620. SIAE4:    bit   7,C             ; hat HDLC RX ein Abort empfangen ?
  1621.           call  NZ,HRXRE1       ; ja - eingeschalteten Empfaenger resetten
  1622.  
  1623. SIAE5:    pop   IX              ; Register restaurieren
  1624.           exx
  1625.           ex   AF,AF'
  1626.           ei                    ; Interrupts wieder erlauben
  1627.           reti                  ; das war's
  1628.  
  1629.  
  1630.  
  1631.  
  1632.  
  1633. ; +---------------------------------------------------------------------+
  1634. ; |                                                                     |
  1635. ; | "SIO channel A Rx Character Available" - Interruptservice           |
  1636. ; |                                                                     |
  1637. ; | Zeichen aus HDLC-Kanal ist angekommen. Ist es das erste Zeichen     |
  1638. ; | eines neuen Frames, dann neuen Framebuffer anlegen, Zeichen merken. |
  1639. ; | Sonst Zeichen merken und vorheriges Zeichen in den Framebuffer      |
  1640. ; | schreiben (vorheriges Zeichen, damit nicht vor dem Anzeigen des     |
  1641. ; | Frameendes CRC-Byte in den Buffer geraet). Bei zu langem Frame      |
  1642. ; | RX resetten und Frame wegwerfen.                                    |
  1643. ; |                                                                     |
  1644. ; +---------------------------------------------------------------------+
  1645.  
  1646. SIARCA:   ex  AF,AF'         ; Register sichern
  1647.           exx
  1648.           push  IX
  1649.           in    A,(SIADAT)      ; Zeichen holen SIO Kanal A (HDLC)
  1650.           ld    HL,HRXSTA       ; RX-State = 1, d.h. "Innerhalb Frame" ?
  1651.           inc   (HL)
  1652.           dec   (HL)
  1653.           jr    NZ,SIAR1
  1654.           inc   (HL)            ; nein - "Ausserhalb" -> "Innerhalb Frame"
  1655.           ld    (HRXLCH),A      ;        Zeichen im 1-Zeichen-FIFO merken
  1656.           ld    BC,8001h        ;        neuer HDLC-RX-Buffer
  1657.           call  PUTSRV
  1658.           jr    SIAR2           ;        das war's
  1659.  
  1660. SIAR1:    ld    HL,HRXLCH       ; ja   - "Innerhalb Frame",
  1661.           ld    C,(HL)          ;        altes Zeichen gueltige Info
  1662.           ld    (HL),A          ;        neues altes Zeichen
  1663.           ld    B,0000h         ;        gueltiges Zeichen in den
  1664.           call  PUTSRV          ;        HDLC-RX-Buffer schreiben
  1665.           dec   L               ;        Fehler dabei, d.h. Frame zu lang ?
  1666.           call  Z,HRXRES        ;        ja -> HDLC-RX Reset, Frame wegwerfen
  1667.  
  1668.           ld    A,ADC_CH2    ; start S meter reading
  1669.           out    (ADC),A
  1670.  
  1671. SIAR2:    pop   IX              ; Register restaurieren
  1672.           exx
  1673.           ex   AF,AF'
  1674.           ei                    ; Interrupts wieder erlauben
  1675.           reti                  ; das war's
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681. ; +---------------------------------------------------------------------+
  1682. ; |                                                                     |
  1683. ; | "SIO channel A Special Receive Condition" - Interruptservice        |
  1684. ; |                                                                     |
  1685. ; | Bei richtigem Frameende (CRC ok, kein Overrun, volle Bytes) wird    |
  1686. ; | Frame in die HDLC-RX-Frameliste eingehaengt, sonst wird das         |
  1687. ; | aktuelle Frame weggeworden.                                         |
  1688. ; |                                                                     |
  1689. ; +---------------------------------------------------------------------+
  1690.  
  1691. SIASRC:   ex  AF,AF'         ; Register sichern
  1692.           exx
  1693.           push  IX
  1694.           ld    A,1             ; SIO Kanal A (HDLC) RR1 = Fehlerstatus holen
  1695.           out   (SIACTL),A
  1696.           in    A,(SIACTL)
  1697.           ld    B,A             ; Fehlerstatus sichern
  1698.           ld    A,30h           ; SIO Kanal A (HDLC) Error Reset
  1699.           out   (SIACTL),A
  1700. ;
  1701.           in    A,(ADC)        ; read S meter
  1702.           ld    (sig_level_),A    ; put here for l1put() to read
  1703.           ld    A,ADC_CH1    ; load 'start convert channel 1 command'
  1704.           out   (ADC),A        ; into the ADC chip
  1705. ;
  1706.           ld    A,B             ; Fehlerstatus restaurieren
  1707.           ld    BC,8001h        ; "aktiven HDLC-RX-Framebuffer auf den Muell"
  1708.           bit   5,A             ; RX Overrun ?
  1709.           jr    Z, SIAS0        ; no, skip on to SIAS0
  1710.           ld    HL,(l2stats_+(8*8)) ; increment port 0 rx overrun count
  1711.           inc   HL
  1712.           ld    (l2stats_+(8*8)),HL
  1713.           jr    SIAS1
  1714. ;          jr    NZ,SIAS1        ; ja   - Frame wegwerfen
  1715. SIAS0:
  1716.           bit   7,A             ; End of Frame ?
  1717.           jr    Z,SIAS2         ; nein - nix tun (war "All Sent")
  1718.           bit   6,A             ; CRC Fehler ?
  1719.           jr    NZ,SIAS3        ; invalid, bump error count
  1720. ;          jr    NZ,SIAS1        ; ja   - Frame wegwerfen
  1721.           and   0Eh             ; nein - war Frame modulo 8 Bit und letztes
  1722.                                 ;        gueltiges Zeichen vorletztes 
  1723.                                 ;        Zeichen (letztes in Buffer) ?
  1724.           cp    6
  1725.           jr    Z, SIAS00       ; yes, frame OK, so skip over
  1726. SIAS3:    ld    A,(SIARR0)
  1727.           bit   3,A
  1728.           jr    Z,SIAS1
  1729.           ld    HL,(l2stats_+80) ; no - bump crc error count
  1730.           inc   HL
  1731.           ld    (l2stats_+80),HL
  1732.           jr    SIAS1
  1733. ;          jr    NZ,SIAS1        ; nein - Frame wegwerfen
  1734. SIAS00:   dec   C               ; ja   - Frame ok, in HDLC-RX-Liste haengen
  1735. SIAS1:    call  HRXNEW          ; Bufferkommando ausfuehren, Frame zuende
  1736.  
  1737. SIAS2:    pop   IX              ; Register restaurieren
  1738.           exx
  1739.           ex   AF,AF'
  1740.           ei                    ; Interrupts wieder erlauben
  1741.           reti                  ; das war's
  1742.  
  1743.  
  1744.  
  1745.  
  1746.  
  1747. ; +---------------------------------------------------------------------+
  1748. ; |                                                                     |
  1749. ; | "Hostterminal TX FIFO character out"                                |
  1750. ; |                                                                     |
  1751. ; | Wenn noch Zeichen im Hostterminal-TX-FIFO, dann Zeichen aus diesem  |
  1752. ; | FIFO holen und an RS232 ausgeben.                                   |
  1753. ; |                                                                     |
  1754. ; | A, DE, HL bentzt.                                                   |
  1755. ; |                                                                     |
  1756. ; +---------------------------------------------------------------------+
  1757.  
  1758. HTXFCO:   ld    HL,(HOTXCC)     ; Zeichen in TX-FIFO ?
  1759.           ld    A,H
  1760.           or    L
  1761.           ret   Z               ; nein - nix tun
  1762.           dec   HL              ; ja   - TX-FIFO Zeichenzaehler - 1
  1763.           ld    (HOTXCC),HL
  1764.           ld    HL,(HOTXOP)     ; Zeiger auf Zeichen
  1765.           ld    A,(HL)          ; Zeichen holen
  1766.           out   (SIBDAT),A      ; an SIO Kanal B (RS232) ausgeben
  1767.           inc   HL              ; Zeiger auf naechstes Zeichen
  1768.           ex    DE,HL
  1769.           ld    HL,HOTXFI+HOTXFL-1      ; Zeiger > letzte FIFO-Stelle, d.h.
  1770.           or    A                       ; "FIFO Wrap Around" ?
  1771.           sbc   HL,DE
  1772.           jr    NC,HTXFC1       ; nein -
  1773.           ld    DE,HOTXFI       ; ja   - Zeiger wieder auf FIFO-Anfang
  1774. HTXFC1:   ld    (HOTXOP),DE     ; Zeiger abspeichern
  1775.           ret                   ; das war's
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781. ; +---------------------------------------------------------------------+
  1782. ; |                                                                     |
  1783. ; | CTXINI   "Crosslink TX initialize"                                  |
  1784. ; |   Sender initialisieren, ggf. mit "Async"-WAIT.                     |
  1785. ; |   A = 1  ->  Sender mit "Async"-WAIT initialiseren                  |
  1786. ; |   A = 2  ->  Sender ohne "Async"-WAIT initialisieren, gleich zu     |
  1787. ; |              CTXPRE                                                 |
  1788. ; |                                                                     |
  1789. ; | CTXPRE   "Crosslink TX preset"                                      |
  1790. ; |   2,5 msec Crosslink-"Vorlauftraeger" setzen.                       |
  1791. ; |                                                                     |
  1792. ; | CTXSTX   "Crosslink TX start of text"                               |
  1793. ; |   Crosslinkframe beginnen mit ASCII Start of Text.                  |
  1794. ; |                                                                     |
  1795. ; | A, DE, HL benutzt.                                                  |
  1796. ; |                                                                     |
  1797. ; +---------------------------------------------------------------------+
  1798.  
  1799.           public raisedcd_
  1800.           extrn  sentdata_
  1801.  
  1802. CTXINI:   inc   A               ; naechster Sendestatus 1/2 -> 3/4
  1803.           inc   A
  1804.           ld    HL,CTXSTA
  1805.           ld    (HL),A
  1806.           cp    4               ; erstes Frame zu digipeatendes Frame ?
  1807.           jr    Z,CTXPRE        ; nein - kein "Async"-WAIT
  1808.           call  random_         ; ja   - "Async"-WAIT beachten
  1809.           and   1Fh             ;        3 < A < 32 = 2,5 msec ... 25 msec
  1810.           or    03h             ;        (1200Hz/3 ... 1200Hz/32)
  1811.           ld    (CTXWAI),A
  1812.           ret
  1813.  
  1814. CTXPRE:   call  raisedcd_
  1815.           ld    A,3             ; 2,5 msec (1200Hz/3)
  1816.           ld    (CTXWAI),A
  1817.           ret                   ; das war's
  1818.  
  1819. CTXSTX:   xor   A
  1820.           ld    (CTXFCS),A      ; Sende-Framechecksumme initialisieren
  1821.           ld    (CTXCSA),A      ; "kein STX/ETX/DLE innerhalb Frame"
  1822.           ld    A,1
  1823.           ld    (sentdata_+1),A ; port flush - mark data as sent
  1824.           ld    A,(crlmod_)     ; check for KISS mode
  1825.           or    A
  1826.           jr    Z,CTXST0        ; jump if not KISS
  1827.           ld    (HL),12         ; else change to state 12
  1828.           ld    A,FEND          ; and send a frame start character
  1829.           jr    CTXST1
  1830. CTXST0:   ld    (HL),5          ; Sendestatus "Innerhalb Crosslink-Frame"
  1831.           ld    A,ASTX          ; Frame beginnt mit ASCII STX,
  1832. CTXST1:   out   (SIBDAT),A      ; Interruptsender an-"kicken"
  1833.           ret                   ; das war's
  1834.  
  1835.  
  1836. raisedcd_: ld    A,5             ; 2,5 msec Crosslink-"Vorlauftraeger" setzen
  1837.           out   (SIBCTL),A
  1838.           ld    HL,SIBWR5
  1839.           res   1,(HL)          ; "/RTS high after TX empty" -> /RTS high
  1840.           ld    A,(HL)          ; = Modemstecker CTS low
  1841.           out   (SIBCTL),A      ; = Crosslink-"Traeger" ein
  1842.           ret
  1843.  
  1844.  
  1845. ; +---------------------------------------------------------------------+
  1846. ; |                                                                     |
  1847. ; | HOINIT   "Host initialize"                                          |
  1848. ; |   Alle Hostterminal-FIFO's (RX und TX) resetten, Crosslink-         |
  1849. ; |   "Traeger" ausschalten.                                            |
  1850. ; |                                                                     |
  1851. ; | CCOFF   "Crosslink carrier off"                                     |
  1852. ; |   Crosslink-"Traeger" ausschalten = Pin /RTS low = Modemstecker     |
  1853. ; |   CTS high.                                                         |
  1854. ; |                                                                     |
  1855. ; | A, HL benutzt.                                                      |
  1856. ; |                                                                     |
  1857. ; +---------------------------------------------------------------------+
  1858.  
  1859.           public dropdcd_
  1860.  
  1861. HOINIT:   ld    HL,0
  1862.           ld    (HORXCC),HL     ; alle Hostterminal-FIFO's resetten
  1863.           ld    (HOTXCC),HL
  1864.           ld    HL,HORXFI
  1865.           ld    (HORXIP),HL
  1866.           ld    (HORXOP),HL
  1867.           ld    HL,HOTXFI
  1868.           ld    (HOTXIP),HL
  1869.           ld    (HOTXOP),HL
  1870.           xor   A
  1871.           ld    (hststs_),A
  1872.  
  1873. dropdcd_:
  1874. CCOFF:    ld    A,5             ; SIO Kanal B (RS232)
  1875.           out   (SIBCTL),A
  1876.           ld    HL,SIBWR5       ; Pin /RTS low = Modemstecker CTS high
  1877.           set   1,(HL)          ;              = Crosslink-"Traeger aus"
  1878.           ld    A,(HL)
  1879.           out   (SIBCTL),A
  1880.           ret
  1881.  
  1882.  
  1883.  
  1884.  
  1885.  
  1886. ; +---------------------------------------------------------------------+
  1887. ; |                                                                     |
  1888. ; | HTXINI   "HDLC TX initialize"                                       |
  1889. ; |   Sender initialisieren, ggf. mit WAIT.                             |
  1890. ; |   A = 1  ->  Sender mit WAIT initialiseren                          |
  1891. ; |   A = 2  ->  Sender ohne WAIT initialisieren, gleich zu HTXKUP      |
  1892. ; |                                                                     |
  1893. ; | HTXKUP   "HDLC TX key up"                                           |
  1894. ; |   HDLC RX abschalten, Sender einschalten, PTT ein, TXDELAY starten. |
  1895. ; |                                                                     |
  1896. ; | HTXSOF   "HDLC TX start of frame"                                   |
  1897. ; |   Zeichen aus TX-Framebuffer holen und mit diesem Zeichen neues     |
  1898. ; |   Frame beginnen.                                                   |
  1899. ; |                                                                     |
  1900. ; | A, DE, HL benutzt.                                                  |
  1901. ; |                                                                     |
  1902. ; +---------------------------------------------------------------------+
  1903.  
  1904.           extrn Wpar_           ; WAIT-Parameter in 10 msec
  1905.           extrn Ppar_           ; P-Persistenz-Wert
  1906.           extrn Tpar_           ; TXDELAY-Parameter in 10 msec
  1907.  
  1908. HTXINI:   inc   A               ; naechster Sendestatus 1/2 -> 3/4
  1909.           inc   A
  1910.           ld    (HL),A
  1911.           cp    4               ; erstes Frame zu digipeatendes Frame ?
  1912.           jr    Z,HTXKUP        ; ja   - kein WAIT beachten
  1913.           ld    A,(Dpar_)       ; nein - Vollduplexbetrieb ?
  1914.           or    A
  1915.           jr    NZ,HTXIN1       ; ja   - Sender sofort hochfahren
  1916.           push  HL              ; nein - (Zeiger auf HTXSTA sichern)
  1917.           call  random_         ; Zufallszahl <= P-Persistenz-Wert ?
  1918.           ld    A,(Ppar_)
  1919.           cp    L
  1920.           pop   HL              ; (Zeiger auf HTXSTA wiedereinsetzen)
  1921.           jr    NC,HTXIN1       ; ja   - Sender hochfahren
  1922.           ld    A,(Wpar_)       ; nein - Slottime abwarten
  1923.           ld    (HTXWAI),A
  1924.           or    A               ; falls Slottime = 0 gleich weiter
  1925.           ret   NZ
  1926.  
  1927. HTXIN1:   inc   (HL)            ; TX-State 3 -> 4
  1928. HTXKUP:   ld    A,(Dpar_)       ; Vollduplexbetrieb ?
  1929.           or    A
  1930.           jr    NZ,HTXKU0
  1931.           ld    A,3             ; nein - "RX disable" = HDLC-Empfaenger
  1932.           out   (SIACTL),A      ;        abschalten
  1933.           ld    A,(SIAIW3)
  1934.           res   0,A
  1935.           out   (SIACTL),A
  1936. HTXKU0:   ld    A,5             ; "TX enable", Pin /RTS low =
  1937.           out   (SIACTL),A      ; HDLC-Sender einschalten, PTT ein
  1938.           ld    A,1
  1939.           ld    (sentdata_),A   ; port flush - mark data as sent
  1940.           ld    HL,SIAWR5
  1941.           set   3,(HL)
  1942.           set   1,(HL)
  1943.           ld    A,(HL)
  1944.           out   (SIACTL),A      ; (geaenderten Sende-Modus merken)
  1945.           ld    A,(Tpar_)       ; TXDELAY in Wartezaehler
  1946.           ld    (HTXWAI),A
  1947.           or    A               ; TXDELAY-Parameter > 0 ?
  1948.           ret   NZ              ; ja   - TXDELAY abwarten
  1949.           ld    HL,HTXSTA       ; nein - kein TXDELAY (TX State = 5)
  1950.           inc   (HL)
  1951. HTXSOF:   ld    HL,0            ; "Zeichen holen aus HDLC-TX-Framebuffer"
  1952.           call  GETSRV          ; Zeichen holen in L
  1953.           ld    A,80h           ; "Reset HDLC TX CRC Generator"
  1954.           out   (SIACTL),A
  1955.           ld    A,L             ; Zeichen ausgeben, erstes Zeichen in Frame,
  1956.           out   (SIADAT),A      ; dadurch Interrupt-Sender ange-"kickt"
  1957.           ld    A,0C0h          ; "Reset HDLC TX Underrun/EoM Latch",
  1958.           out   (SIACTL),A      ; damit Frameende erkannt werden kann
  1959.           ret                   ; das war's
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965. ; +---------------------------------------------------------------------+
  1966. ; |                                                                     |
  1967. ; | "get service"                                                       |
  1968. ; |                                                                     |
  1969. ; | l1get-Aufruf mit HL als Parameter, Ergebnis in HL zurueck.          |
  1970. ; | Auch von innerhalb Interruptroutinen aufrufbar, da Interrupt-       |
  1971. ; | verbietungsstufe beibehalten wird,  o h n e  ggf. ein EI bei        |
  1972. ; | l1get-Aufruf auszuloesen.                                           |
  1973. ; |                                                                     |
  1974. ; | l1get ist die TX-Buffer-Verwaltung, Zeichen holen, Kommandos zur    |
  1975. ; | Bufferbehandlung, Meldungen zum Bufferzustand.                      |
  1976. ; |                                                                     |
  1977. ; | A, DE benutzt.                                                      |
  1978. ; |                                                                     |
  1979. ; +---------------------------------------------------------------------+
  1980.  
  1981.           extrn l1get_       ; C TX-Buffer-Verwaltung
  1982.  
  1983. GETSRV:   push  HL              ; Aufrufparameter fuer C-Routine l1get
  1984.           ld    HL,DEICNT       ; zu fruehes EI durch l1get verhindern
  1985.           inc   (HL)
  1986.           call  l1get_          ; C-Routine l1get ausfuehren
  1987.           ex    DE,HL           ; Ergebnis von l1get in DE
  1988.           ld    HL,DEICNT       ; wieder alte Interrupt-Verbietungsstufe
  1989.           dec   (HL)
  1990.           ex    DE,HL           ; Ergebnis von l1get in HL
  1991.           pop   DE              ; Stack korrigieren (l1get Parameter)
  1992.           ret                   ; das war's
  1993.  
  1994.  
  1995.  
  1996.  
  1997.  
  1998. ; +---------------------------------------------------------------------+
  1999. ; |                                                                     |
  2000. ; | HRXRES   "HDLC RX Reset"                                            |
  2001. ; |   HDLC RX neu anfangen lassen, SIO und Buffer initialisieren.       |
  2002. ; |                                                                     |
  2003. ; | HRXRE1                                                              |
  2004. ; |   Wie HRXRES, aber SIO in Ruhe lassen, nur Buffer initialisieren.   |
  2005. ; |                                                                     |
  2006. ; | HRXNEW   "HDLC RX New"                                              |
  2007. ; |   Wie PUTSRV, am Frameende. Restzeichen aus SIO entfernen,          |
  2008. ; |   Empfangsstatus initialiseren fuer naechstes Frame.                |
  2009. ; |                                                                     |
  2010. ; | PUTSRV   "put service"                                              |
  2011. ; |   l1put-Aufruf mit BC als Parameter, Ergebnis in HL zurueck.        |
  2012. ; |   Auch von innerhalb Interruptroutinen aufrufbar, da Interrupt-     |
  2013. ; |   verbietungsstufe beibehalten wird,  o h n e  ggf. ein EI bei      |
  2014. ; |   l1get-Aufruf auszuloesen.                                         |
  2015. ; |                                                                     |
  2016. ; | l1put ist die RX-Buffer-Verwaltung, Zeichen schreiben, Kommandos    |
  2017. ; | zur Bufferbehandlung, Meldungen zum Bufferzustand.                  |
  2018. ; |                                                                     |
  2019. ; | A, BC, DE benutzt.                                                  |
  2020. ; |                                                                     |
  2021. ; +---------------------------------------------------------------------+
  2022.  
  2023.           extrn l1put_       ; C RX-Buffer-Verwaltung
  2024.           public HRXRES
  2025.  
  2026. HRXRES:   ld    A,03h           ; SIO Kanal A, RX CRC enable, CRC enable,
  2027.           out   (SIACTL),A      ; Hunt Phase (initiales WR3)
  2028.           ld    A,(SIAIW3)
  2029.           out   (SIACTL),A
  2030. HRXRE1:   ld    BC,8001H        ; aktiven RX-Framebuffer auf den Muell,
  2031.                                 ; wenn nicht leer, sonst neuen beginnen
  2032. HRXNEW:   in    A,(SIADAT)      ; Zeichen aus HDLC-Kanal holen und vergessen
  2033.           xor   A               ; HDLC RX-State : "RX ausserhalb Frame"
  2034.           ld    (HRXSTA),A
  2035. PUTSRV:   push  BC              ; Aufrufparameter fuer l1put
  2036.           ld    HL,DEICNT       ; zu fruehes EI durch l1put verhindern
  2037.           inc   (HL)
  2038.           call  l1put_          ; C-Routine l1put ausfuehren
  2039.           ex    DE,HL           ; l1put-Returnwert merken
  2040.           ld    HL,DEICNT       ; wieder alte Interrupt-Verbietungsstufe
  2041.           dec   (HL)
  2042.           ex    DE,HL           ; l1put-Returnwert restaurieren
  2043.           pop   BC              ; Stack korrigieren (l1put Parameter) 
  2044.           ret                   ; das war's
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050. ; +---------------------------------------------------------------------+
  2051. ; |                                                                     |
  2052. ; | C :  BOOLEAN iscd(port) unsigned port;   "is carrier detect"        |
  2053. ; |                                                                     |
  2054. ; | Test, ob Port (Kanal) mit Nummer port belegt ist (d.h. nicht        |
  2055. ; | gesendet werden darf).                                              |
  2056. ; |                                                                     |
  2057. ; |   port = 0 :  HDLC Modemport                                        |
  2058. ; |        = 1 :  RS232 Crosslinkport                                   |
  2059. ; |                                                                     |
  2060. ; |                                                                     |
  2061. ; | TRUE   -  (HL=1, Z=0) Kanal ist belegt                              |
  2062. ; |                                                                     |
  2063. ; | FALSE  -  (HL=0, Z=1) Kanal ist frei (oder Vollduplex-HDLC)         |
  2064. ; |                                                                     |
  2065. ; |                                                                     |
  2066. ; | A benutzt, HL Returnwert.                                           |
  2067. ; |                                                                     |
  2068. ; +---------------------------------------------------------------------+
  2069.  
  2070.           public iscd_
  2071.  
  2072. iscd_:    ld    HL,2            ; Portnummer als 16-Bit-C-Parameter vom
  2073.           add   HL,SP           ; Stack holen
  2074.           ld    A,(HL)
  2075.           ld    HL,0            ; default Returnwert FALSE
  2076.           dec   A               ; Crosslink-Port (RS232), d.h. 1 ?
  2077.           jr    NZ,iscd2        ; nein -
  2078.  
  2079. ;
  2080. ; Crosslink-Port
  2081. ;
  2082.           ld    A,(SIBRR0_)      ; ja   - SIO Kanal B Status holen
  2083.           and   00100000b       ; Pin /CTS low = Modem DTR high ("1") ?
  2084.           jr    NZ,iscd1
  2085.           inc   A               ; nein - H=1, Z=0, TRUE zurueck
  2086.           ld    L,A             ;        (Kanal belegt)
  2087.           ret
  2088. iscd1:    xor   A               ; ja   - H=0, Z=1, FALSE zurueck
  2089.           ret                   ;        (Kanal frei)
  2090.  
  2091. ;
  2092. ; HDLC-Port
  2093. ;
  2094. iscd2:    ld    A,(Dpar_)       ; Vollduplexbetrieb ?
  2095.           dec   A
  2096.           ret   Z               ; ja - Z = 1, A = 0, HL = 0, FALSE
  2097.           ld    A,(SIARR0)      ; SIO Kanal A Status holen
  2098.           bit   3,A             ; SIO Kanal A DCD an ?
  2099.           ret   Z               ; nein - FALSE zurueck (Kanal frei)
  2100.           inc   HL              ; ja   - TRUE zurueck (Kanal belegt)
  2101.           ret
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107. ; +---------------------------------------------------------------------+
  2108. ; |                                                                     |
  2109. ; | C :  BOOLEAN ishost()   "is host terminal"                          |
  2110. ; |                                                                     |
  2111. ; | Rueckgabe :   TRUE,  HL = 1, Z = 0  -  Hostterminal an RS232        |
  2112. ; |               FALSE, HL = 0, Z = 1  -  Crosslink an RS232           |
  2113. ; |                                                                     |
  2114. ; | A benutzt.                                                          |
  2115. ; |                                                                     |
  2116. ; +---------------------------------------------------------------------+
  2117.  
  2118.           public ishost_
  2119.  
  2120. ishost_:  ld    HL,0            ; Rueckgabe-Preset FALSE
  2121.           ld    A,(SIBRR0_)      ; DCD an RS232 (SIO Kanal B) ?
  2122.           and   00001000b
  2123.           ret   Z               ; nein - FALSE zurueck (Crosslink)
  2124.           inc   HL              ; ja   - TRUE zurueck  (Hostterminal)
  2125.           ret                   ; das war's
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131. ; +---------------------------------------------------------------------+
  2132. ; |                                                                     |
  2133. ; | C :  char *minmem()   "minimum memory"                              |
  2134. ; |                                                                     |
  2135. ; | Niedrigste nutzbare RAM-Freispeicherstelle in HL zurueck,           |
  2136. ; | Test auf 0 fuer C-Kompatibilitaet.                                  |
  2137. ; |                                                                     |
  2138. ; | A benutzt.                                                          |
  2139. ; |                                                                     |
  2140. ; +---------------------------------------------------------------------+
  2141.  
  2142.           public minmem_
  2143.  
  2144. ;         extrn fremem_      ; erste Speicherstelle Freispeicher
  2145.       extrn Fremem_
  2146.  
  2147. minmem_:
  2148. ;      ld    HL,fremem_      ; niedrigste nutzbare RAM-Freispeicherstelle
  2149.       ld    HL,(Fremem_)    ; ** COMPILER DIFFERENCE !!!! ** - Aztec C
  2150.           ld    A,H             ; als C-Funktionswert zurueck
  2151.           or    L
  2152.           ret                   ; das war's
  2153.  
  2154.  
  2155.  
  2156.  
  2157.  
  2158. ; +---------------------------------------------------------------------+
  2159. ; |                                                                     |
  2160. ; | C :  char *maxmem()   "maximum memory"                              |
  2161. ; |                                                                     |
  2162. ; | Hoechste nutzbare RAM-Freispeicherstelle in HL zurueck,             |
  2163. ; | Test auf 0 fuer C-Kompatibilitaet.                                  |
  2164. ; |                                                                     |
  2165. ; | A benutzt.                                                          |
  2166. ; |                                                                     |
  2167. ; +---------------------------------------------------------------------+
  2168.  
  2169.           public maxmem_
  2170.  
  2171. maxmem_:  ld    HL,(RAMTOP)     ; hoechste nutzbare RAM-Freispeicherstelle
  2172.           ld    A,H             ; als C-Funktionswert zurueck
  2173.           or    L
  2174.           ret                   ; das war's
  2175.  
  2176.  
  2177.  
  2178.  
  2179.  
  2180. ; +---------------------------------------------------------------------+
  2181. ; |                                                                     |
  2182. ; | C :  VOID DIinc()   "disable interrupt increment"                   |
  2183. ; |                                                                     |
  2184. ; | Interrupts verbieten, Verbietungsstufe erhoehen.                    |
  2185. ; |                                                                     |
  2186. ; |                                                                     |
  2187. ; | HL benutzt.                                                         |
  2188. ; |                                                                     |
  2189. ; +---------------------------------------------------------------------+
  2190.  
  2191.           public DIinc_
  2192.  
  2193. DIinc_:   di                    ; Interrupts verbieten
  2194.           ld    HL,DEICNT       ; auf die naechste Verbietungsstufe
  2195.           inc   (HL)
  2196.           ret                   ; das war's
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202. ; +---------------------------------------------------------------------+
  2203. ; |                                                                     |
  2204. ; | C :  VOID decEI()   "decrement enable interrupt"                    |
  2205. ; |                                                                     |
  2206. ; | Verbietungsstufe erniedrigen, wenn dann gleich 0, Interrupts        |
  2207. ; | wieder erlauben.                                                    |
  2208. ; |                                                                     |
  2209. ; | HL benutzt.                                                         |
  2210. ; |                                                                     |
  2211. ; +---------------------------------------------------------------------+
  2212.  
  2213.           public decEI_
  2214.  
  2215. decEI_:   ld    HL,DEICNT       ; Verbietungsstufe - 1
  2216.           dec   (HL)            ; Erlaubnis erreicht ?
  2217.           ret   NZ              ; nein - dann war's das
  2218.           ei                    ; ja   - Interrupts wieder erlauben
  2219.           ret                   ; das war's
  2220.  
  2221.  
  2222.  
  2223.  
  2224.  
  2225. ; +---------------------------------------------------------------------+
  2226. ; |                                                                     |
  2227. ; | C :  BOOLEAN CONled(on)   BOOLEAN on;   "CONNECT-LED"               |
  2228. ; |                                                                     |
  2229. ; | Ein- oder Ausschalten der CONNECT-LED.                              |
  2230. ; |                                                                     |
  2231. ; | Parameter :  on = TRUE,  1   ->   LED anschalten                    |
  2232. ; |              on = FALSE, 0   ->   LED ausschalten                   |
  2233. ; |                                                                     |
  2234. ; | A, HL benutzt.                                                      |
  2235. ; |                                                                     |
  2236. ; +---------------------------------------------------------------------+
  2237.  
  2238. ;          public CONled_
  2239.  
  2240. ;CONled_:  di                    ; Int's duerfen nicht dazwischenfunken
  2241. ;          ld    A,5             ; /DTR-Pin = LED-Ausgang wird ueber SIO
  2242. ;          out   (SIBCTL),A      ; Register 5 angesteuert
  2243. ;          ld    HL,2            ; Zeiger auf Parameter
  2244. ;          add   HL,SP
  2245. ;          ld    A,(HL)          ; Parameter low Byte holen
  2246. ;          rrca                  ; Bit 0 -> Bit 7
  2247. ;          xor   80h             ; Bit 0-6 loeschen, Bit 7 invertieren
  2248. ;          ld    HL,SIBWR5
  2249. ;          res   7,(HL)          ; SIO B /DTR Pin entsprechend Parameter
  2250. ;          or    (HL)            ; (on = TRUE -> Pin /DTR low -> LED ein)
  2251. ;          ld    (HL),A
  2252. ;          out   (SIBCTL),A      ; selbiges auch merken
  2253. ;          ei                    ; Interrupts wieder erlauben
  2254. ;          ret                   ; das war's
  2255.  
  2256.  
  2257.  
  2258.  
  2259.  
  2260. ; +---------------------------------------------------------------------+
  2261. ; |                                                                     |
  2262. ; | C :  BOOLEAN STAled(on)   BOOLEAN on;   "STATUS-LED"                |
  2263. ; |                                                                     |
  2264. ; | Ein- oder Ausschalten der STATUS-LED.                               |
  2265. ; |                                                                     |
  2266. ; | Parameter :  on = TRUE,  1   ->   LED anschalten                    |
  2267. ; |              on = FALSE, 0   ->   LED ausschalten                   |
  2268. ; |                                                                     |
  2269. ; | A, HL benutzt.                                                      |
  2270. ; |                                                                     |
  2271. ; +---------------------------------------------------------------------+
  2272.  
  2273. ;          public STAled_
  2274.  
  2275. ;STAled_:  di                    ; Int's duerfen nicht dazwischenfunken
  2276. ;          ld    A,5             ; /DTR-Pin = LED-Ausgang wird ueber SIO
  2277. ;          out   (SIACTL),A      ; Register 5 angesteuert
  2278. ;          ld    HL,2            ; Zeiger auf Parameter
  2279. ;          add   HL,SP
  2280. ;          ld    A,(HL)          ; Parameter low Byte holen
  2281. ;          rrca                  ; Bit 0 -> Bit 7
  2282. ;          xor   80h             ; Bit 0-6 loeschen, Bit 7 invertieren
  2283. ;          ld    HL,SIAWR5
  2284. ;          res   7,(HL)          ; SIO A /DTR Pin entsprechend Parameter
  2285. ;          or    (HL)            ; (on = TRUE -> Pin /DTR low -> LED ein)
  2286. ;          ld    (HL),A
  2287. ;          out   (SIACTL),A      ; selbiges auch merken
  2288. ;          ei                    ; Interrupts wieder erlauben
  2289. ;          ret                   ; das war's
  2290.  
  2291.  
  2292.  
  2293.  
  2294.  
  2295. ; +---------------------------------------------------------------------+
  2296. ; |                                                                     |
  2297. ; | C :  VOID srand()                                                   |
  2298. ; |                                                                     |
  2299. ; | Zufallszahlengenerator initialisieren.                              |
  2300. ; |                                                                     |
  2301. ; +---------------------------------------------------------------------+
  2302.  
  2303.           public srand_
  2304.  
  2305. srand_:   ld    A,R             ; 0 <= A <=127 (oder 128 <= A <= 255)
  2306.           ld    L,A             ; URAND = A
  2307.           ld    H,0
  2308.           ld    (URAND),HL
  2309.           ret
  2310.  
  2311.  
  2312.  
  2313.  
  2314.  
  2315. ; +---------------------------------------------------------------------+
  2316. ; |                                                                     |
  2317. ; | C :  unsigned random()                                              |
  2318. ; |                                                                     |
  2319. ; | 8-Bit Quasi-Zufallszahl (0..255) holen in A und HL.                 |
  2320. ; |                                                                     |
  2321. ; +---------------------------------------------------------------------+
  2322.  
  2323.           public random_
  2324.  
  2325. random_:  ld    HL,(URAND)      ; URAND rueckgekoppelt linksschieben
  2326.           ld    A,H             ; (Zweck: Gleichverteilung random())
  2327.           and   01100000b
  2328.           jp    PO,rand1
  2329.           scf
  2330. rand1:    adc   HL,HL
  2331.           ld    (URAND),HL
  2332.           ld    A,R             ; 0 <= A <=127 (oder 128 <= A <= 255)
  2333.           add   A,A             ; 0 <= A <= 254, gerade
  2334.           inc   A               ; 1 <= A <= 255, ungerade
  2335.           xor   L               ; 0 <= A <= 255
  2336.           ld    L,A             ; HL = A
  2337.           ld    H,0             ; (nur LSB signifikant)
  2338.           ret                   ; das war's
  2339.  
  2340.           end
  2341.